Unity:ECS的核心概念

时间:2021-07-15 | 标签: | 作者:Q8 | 来源:郑洪智网络

小提示:您能找到这篇{Unity:ECS的核心概念}绝对不是偶然,我们能帮您找到潜在客户,解决您的困扰。如果您对本页介绍的Unity:ECS的核心概念内容感兴趣,有相关需求意向欢迎拨打我们的服务热线,或留言咨询,我们将第一时间联系您!

< ">ECS架构的核心是数据,这也是为什么Unity会将这一套技术栈命名为DOTS。System会读取entity上面的component的数据流,并处理数据。实体在这里其实更像是索引,它本身并不包含任何数据和逻辑。

< font-size: 16px;">ECS包含三个部分:实体(entities)、数据(components)、行为(system)。具体看下图:

< font-size: 16px;">

< font-size: 16px;">这个图中,System读取了多个实体的Translation和Rotation组件,然后经过计算处理,将结果更新到LocalToWorld组件中。

< font-size: 16px;">从图中你可以看到,实体A和B还有Renderer组件,但是C并没有。不过这并不会影响System的计算逻辑,因为这个系统不关心Renderer组件。

< font-size: 16px;">你还可以写一个系统,需要处理Renderer组件,这样系统就会忽略实体C。你还可以写一个系统排除包含Renderer组件的实体,这样系统就会忽略实体A和B。

< font-size: 16px;">下面对ECS中比较重要的几个核心概念做一个梳理:

< font-size: 16px;">原型 Archetypes

< font-size: 16px;">多个组件的组合叫做一个原型。

< font-size: 16px;">比如一个3D物体可能会包含用于transform的组件,包括移动、旋转、渲染,每个3D物体对应一个实体,但是他们都有同样的组件,所以ECS会把他们分类成是一类原型。

< font-size: 16px;">

< font-size: 16px;">在上图中,实体A和B的原型都是M,实体C的原型是N。



< font-size: 16px;">你也可以通过在运行时添加或者移除component来改变一个实体的原型。例如:如果将实体B的Renderer组件移除,实体B的原型就会变成N。

< font-size: 16px;">内存块 Memory Chunk海尔洗衣机危机公关内容s

< font-size: 16px;">为什么要先讲原型的概念呢,因为一个实体的原型是什么,决定了ECS会将实体的components也就是数据存在什么地方。ECS按块分配内存,每块用一个ArchetypeChunk对象表示。



< font-size: 16px;">一个块只包含一种原型,可以包含的多个实体的数据。如果一个块的内存满了,ECS会分配一个新的块来存储新的实体的components。

< font-size: 16px;">如果你修改了实体的组件,那就相当于修改了实体的原型,这时候ECS会将实体的组件数据移到另外一个块中。

< font-size: 16px;">

< font-size: 16px;">原型和内存块的关系是一对多的关系。这就意味着,如果想查询给定的一组component类型的所有实体,只需要在这些原型中搜索即可。这样会比在所有的实体中查找效率高很多。

< font-size: 16px;">ECS在存储实体到内存块中没有特殊的排序,当创建一个实体或者实体的原型发生变化时,ECS会将它放到对应原型的第一个还有空间的内存块中。内存块中的数据会紧密排列。如果一个实体要被移出当前原型的内存块,这时候会有个空位,ECS会把这个内存块最后的实体数据移动到这个空位中。

< font-size: 16px;">注意:原型中的共享组件(后面会具体说这是个运营营销电商什么东东)的数据也会影响实体会被存在哪个内存块。同一个内存块中的所有实体的共享组件中的数据值都是相同的。如果你修改了共享组件中的数据,这个实体会被移到另外一个块中,有点类似修改了实体的原型。

< font-size: 16px;">将共享组件的实体分到一个内存块中会提高处理他们的速度。比如Hybird Renderer(混合渲染)定义了RenderMesh组件来达成这个目的。

< font-size: 16px;">实体查询

< font-size: 16px;">一个System根据什么来决定处理哪些实体呢?这时候会用到一个叫实体查询(Entity Query)的东西。实体查询首先需要一些组件类型,然后根据你传入的组件类型的组合,在包含这些组件的原型中查询符合要求的实体。查询时可以指定下面三种类型:

< font-size: 16px;">All 必须包含All中所有的组件类型

< font-size: 16px;">Any 必须包含Any中至少一个组件类型

< font-size: 16px;">None 不能包含None中任意一个组件类型

< font-size: 16px;">一次实体查询的结果会返回所有符合查询要求的内存块,你可以使用IJobChunk来迭代遍历所有的组件。(IJobChunk后面会讲。)

< font-size: 16px;">Jobs 作业

< font-size: 16px;">之前说过,ECS配合Job使用才能发挥多线程的威力。ECS提供了SystemBase类,其中包含Entities.ForEach方法,还包含了IJobChunk的Schedule()和ScheduleParallel()方法,可以在子线程中处理数据。Entities.ForEach是最简单的方法,只需要几行代码就能实现。IJobChunk可以用来处理比较复杂的情况。

< font-size: 16px;">ECS会在主线程调度Job,根据System的顺序。当job调度后,ECS会追踪哪些job在读写哪些组件。需要读权限的job需要等待前面写权限的job执行完,反之亦然。Job调度器会使用job依赖来决定哪些job可以并行,哪些必须串行。

< font-size: 16px;">System的组织

< font-size: 16px;">ECS通过World和group来组织system。默认情况下,ECS会创建一个默认的World,包含一些预定义的group组。它会找到工程中所有的System,实例化他们,并添加到预定义的group中。

< font-size: 16px;">你可以指定同一个group中system的Update的执行顺序。Group也是一种system,所以你可以将一个group添加到另外一个group中。如果你没有指定顺序,system的执行顺序会不太确定,并不会按照它们创建的顺序。不过,同一个group中的所有system都会比下一个group中的system先执行。

< font-size: 16px;">System的Update是在主线程中执行的,不过可以使用Job将工作分配到子线程中。

< font-size: 16px;">ECS世界的可视化创建(authoring)

< font-size: 16px;">在Unity中没办法直接可视化地创建DOTS世界,但是,可以先用GameOjbect和MonoBehaviour来创建,然后通过转换系统将GameObject转换成实体和组件。这个我们后面也会细讲。

< font-size: 16px;">来源:Unity官方平台

< font-size: 16px;">原文:https://mp.weixin.qq.com/s/Tvtqz51Np7vWeYwKcQtHdQ

Unity:ECS的核心概念

上一篇:【干货】手把手教你突破领英三度人脉(一)
下一篇:中国品牌商欲进军俄语市场?3分钟带你了解Yan


版权声明:以上主题为“Unity:ECS的核心概念"的内容可能是本站网友自行发布,或者来至于网络。如有侵权欢迎联系我们客服QQ处理,谢谢。
相关内容
推荐内容
扫码咨询
    Unity:ECS的核心概念
    打开微信扫码或长按识别二维码

小提示:您应该对本页介绍的“Unity:ECS的核心概念”相关内容感兴趣,若您有相关需求欢迎拨打我们的服务热线或留言咨询,我们尽快与您联系沟通Unity:ECS的核心概念的相关事宜。

关键词:Unity:ECS的核心概念,Unit

关于 | 业务 | 案例 | 免责 | 隐私
客服邮箱:sales@1330.com.cn
电话:400-021-1330 | 客服QQ:865612759
沪ICP备12034177号 | 沪公网安备31010702002418号