Unity DOTS中ECS核心架构详解

  最近DOTS终于发布了正式的版本, 我们来分享一下DOTS中ECS的几个关键概念与结构,方便大家上手学习掌握Unity DOTS开发。

ECS中的World

  Unity DOTS ECS架构中所有的Entity都是被放到了World对象里面,每个Entity在World里面都有唯一的Id号。Unity DOTS 可以同时支持很多个World, DOTS会在运行的时候创建一个默认的World。World包含了它所需的所有System, System迭代计算的时候,使用World里面的Entity中的Component数据。如果不想要一运行就创建一个默认的World,我们可以通过以下宏开关来控制:

#UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_RUNTIME_WORLD
关闭运行模式下启动的时候,创建一个默认的World

#UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_EDITOR_WORLD
关闭编辑器模式下创建默认的World对象

#UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP
关闭掉编辑器模式/运行模式下的默认的World的创建

EntityManager对象

  每个World, 有且只有一个EntityManager对象。EntityManager对象负责Entity的管理,包含但不限于: 创建Entity, 销毁Entity, 修改Entity中的数据等。

Entity对象

  DOTS 中的每一个实体,我们称为Entity, 它本身是一个容器,可以理解为一个轻量级的gameObject, 它的数据全部存放在它的对应的组件里面。Entiy里面的所有组件数据内存会并行一起排布。这样保证了Entity 数据内存的高效访问与Cache命中。相当于把Entity所包含的所有组件数据的内存打包到一个内存块中。比如一个A类Entity, 它包含了有M,N两个组件数据,当我们给Entity来分布组件数据内存的时候,是把M+N两个组件的内存看作一种类型,线性排布在一起分配。存储数据的时候M,就操作这个内存块的M的部分。操作N组件数据的时候,就操作这个内存块的N的部分。Entity中的所有组件组成的内存块看作的这个类型,我们叫做ArchType。相同类型的Entity(所有组件的组成结构相同)属于同一种ArchType。

ArchType与Chunk高效的内存分配器

高效的内存分配器需要具备几个特点:

  1. 高效地分配与释放;

  2. 避免大量的分配与释放后造成的内存碎片;

    上文提到,Entity中的所有组件数据是排布在一块内存里面的,每一种不同的排布,就会对应一种"类型"ArchType, DOTS 高效的内存分配器只需要基于ArchType所对应的内存块大小来进行分配就可以了。DOTS的entity组件数据的内存分配器基于Chunk设计,每个Chunk的大小为16kb,每个Chunk只会分配同一种类型的ArchType, 根据ArchType的组件组合,我们就可以计算出它们一共所需要的内存大小,我们就从Chunk中固定分配对应的内存大小就可以了,这样Entity对应的所有组件内存非常高效的分配与释放,同时每种Chunk只存放一种ArchType类型的内存块,每次分配的内存大小都是一样,这样可以避免内存碎片。基于ArchType的内存排布如下所示:

    ===============================
    ArchType1:
    chunk1【e1(c1c2),e2(c1c2),e3(c1c2)】
    chunk2【e4(c1c2),e5(c1c2),e6(c1c2)】
    ...
    ======================
    ArchType2:
    chunk1【e1(c3c4),e2(c3c4),e3(c3c4)】
    chunk2【e4(c3c4),e5(c3c4),e6(c3c4)】
    ...
    ===============================
    ArchType3: 
    chunk1【e1(c5c6),e2(c5c6),e3(c5c6)】
    chunk2【e3(c5c6),e4(c5c6),e5(c5c6)】
    ...
    ===============================
    
    

System与JobSystem

  我们学C语言的时候,听到过一句名言,程序=数据结构+算法。Entity解决了数据存储的问题,System就是算法。算法所需要的数据,来源于Entity中的Component。DOTS提供机制,System可以访问到entity中的组件数据,拿到这些数据后再做逻辑迭代计算与处理。默认System是运行在Unity的main thread上的,为了发挥多核优势,把可以用多线程处理的任务使用多线程,Unity 还提供了JobSystem机制,通过多线程的线程池来迭代计算JobSystem,不放main thread上提升程序的效率。

  总结如下:

  DOTS中会有一个World对象,每个Word对象会有一个EntityManager负责Entity的管理,内部使用了高效的基于ArchType与Chunk机制的内存分配。所有的system会加入到World里面来进行统一迭代,System可以访问Entity中的Component数据。同时JobSystem可以让我们的算法迭代基于多线程处理。配上总结图如下:

  今天的DOTS系列就分享到这里了,下一节继续。


  尊敬的准VIP客户:

  我们Unity DOTS课程也正式发布了,我们课程经过9年多的更新与迭代,已经涵盖了Unity 开发中遇到的绝大部分问题,涵盖了Unity主程序进阶,升职加薪所需要的系统的知识体系,主流游戏类型的重点难点技术解决方案。我们的老师10:00~23:00提供实时解答与回复,包含但不限于客户端+服务端。相信我们提供的游戏开发技术服务能很好的帮助到您。选择我们的VIP课程,您肯定不会后悔!有兴趣请 + 企.鹅.裙 428 540 563


  下面是DOTS的VIP课程前18节视频,免费观看

Unity DOTS进阶与项目实战(B站18集)

第001课DOTS的环境安装与准备事项

第002课 DOTS的核心机制与概述

第003课DOTS的SubScene

第004课Component的概述与普通组件的Baker

第005课System与SystemGroup概述

第006课DOTS中的ECS核心概念总结

第007课Baking系列之Baking与Baker详解

第008课Baking系列之BakingSystem与BakingWorld详解

第009课FilterBakingOutput与PrefabsInBaking

第010课BlobAsset核心机制分析

第011课Aspect核心机制分析

第012课 StructChange核心机制详解

第013课Managed与Unmanaged Component详解与性能分析

第014课ShareComponent核心机制与性能分析

第015课CleanupComponent核心分析

第016课 Dynamic Buffer Component详解与分析

第017课Tag与Chunk Component详解与分析

第018课Enableable与Singleton组件详解与分析

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值