Unity ECS Manual [0]

63 篇文章 11 订阅

ECS概念

  一个实体组件系统(ECS)架构将身份(entities)、数据(components)和行为(systems)分开。该架构的重点是数据。systems读取components的数据流,然后将数据从输入状态转化为输出状态,然后由实体进行索引。

  下图说明了这三个基本部分如何一起工作:

在这里插入图片描述
  在这个图中,System 读取 Translation 和 Rotation 组件,将其相乘,然后更新相应的 LocalToWorld 组件(L2W = T*R)。

  实体A和B有一个Renderer组件,而实体C没有,这并不影响System,因为System并不关心Renderer组件。

  你可以设置一个System,使其需要一个 Renderer 组件,在这种情况下,系统会忽略实体C的组件;或者,你可以设置一个系统,排除具有Renderer组件的实体,然后忽略实体A和B的组件。

Archetypes(原型)

  组件类型的唯一组合称为EntityArchetype。例如,3D对象可能有一个用于其世界变换的 component,一个用于其线性运动的 component,一个用于旋转的 component,以及一个用于其视觉表示的component。这些3D对象之一的每个实例对应于一个实体,但由于它们共享同一组组件,因此ECS将它们归类为单个Archetypes(原型):

在这里插入图片描述
  在此图中,实体A和B共享原型M,而实体C共享原型N。

  要平滑更改实体的原型,可以在运行时添加或删除组件。例如,如果从Entity B中删除渲染器组件,则它将移动到原型N。

Memory Chunks(内存块)

  实体的原型确定ECS存储该实体的组件的位置。ECS以“块”的形式分配内存,每个块由一个ArchetypeChunk对象表示。块始终包含单个原型的实体。当内存块装满时,ECS会为使用相同原型创建的任何新实体分配新的内存块。如果添加或删除组件(这会更改 entity 原型),ECS会将该 entity 的 components 移动到不同的块中。

在这里插入图片描述
  此组织方案在原型和块之间提供一对多关系。这还意味着,查找具有给定组件集的所有实体只需要搜索现有的原型,这些原型的数量通常很少,而不需要搜索所有的实体,这些实体的数量通常要大得多。

  ECS不按特定顺序存储块中的实体。当实体被创建或更改为新原型时,ECS会将其放入具有空间的第一个存储原型的块中。然而,块仍然被紧密地打包;当一个实体从原型中移除时,ECS将该块中最后一个实体的组件移动到组件数组中新腾出的插槽中。

NOTE
原型中共享组件的值还决定了哪些实体存储在哪个块中。对于任何共享组件,给定块中的所有实体都具有完全相同的值。如果更改共享组件中任何字段的值,则修改后的实体将移动到不同的块中,就像更改该实体的原型时一样。如有必要,将分配新的块。

  当一起处理实体更有效率时,使用共享组件来分组原型内的实体。例如,Hybrid Renderer定义了它的RenderMesh组件来实现这一点。

Entity queries(实体查询)

  为了确定一个系统应该处理哪些实体,请使用EntityQuery。实体查询在现有的原型中搜索那些有符合你要求的组件的原型。你可以用查询指定以下组件要求:

  • All — 原型必须包含所有类别中的所有组件类型。
  • Any — 原型必须至少包含任何类别中的一个组件类型。
  • None — 原型必须不包含无类别中的任何组件类型。

  一个实体查询提供了一个包含查询所需组件类型的块的列表。然后你可以用IJobEntityBatch直接迭代这些块中的组件。

Jobs

  为了利用多线程的优势,你可以使用C# Job系统。ECS提供了SystemBase类,以及Entities.ForEach和IJobEntityBatch Schedule()和ScheduleParallel()方法,用于在主线程之外转换数据。Entities.ForEach的使用最为简单,通常需要较少的代码行来实现。你可以使用IJobChunk来处理Entities.ForEach所不能处理的更复杂的情况。

  ECS按照您的systems安排的顺序在主线程上安排工作。当Jobs被安排时,ECS会跟踪哪些Jobs读取和写入哪些组件。读取一个组件的Job依赖于任何事先安排好的写到同一组件的Job,反之亦然。Jobs调度器使用Job依赖关系来决定哪些Jobs可以并行运行,哪些必须依次运行。

System organization(系统组织)

  ECS按World,然后按Group来组织System。默认情况下,ECS创建了一个具有预定义组的默认世界。它找到所有可用的System,将其实例化,并将其添加到默认世界中预定义的模拟group。

  你可以指定同一组内各系统的更新顺序。一个组是一种系统,所以你可以把一个组添加到另一个组,并像其他系统一样指定其顺序。一个组内的所有系统都会在下一个系统或组之前更新。如果你不指定顺序,ECS会以一种不依赖于创建顺序的确定性方式将系统插入到更新顺序中。换句话说,即使你没有明确指定一个顺序,同一组系统在其组内总是以相同的顺序更新。

  System update发生在主线程上。然而,系统可以使用Jobs来卸载Job到其他线程。SystemBase提供了一个直接的方法来创建和安排Job。

  关于System创建、更新顺序以及你可以用来组织System的属性的更多信息,请参见关于System 更新顺序的文档。

ECS authoring(编写)

  当你在Unity编辑器中创建你的游戏或应用程序时,你可以使用GameObjects和MonoBehaviours来创建一个转换系统,将那些UnityEngine对象和组件映射到实体。了解更多信息,请参见创建Gameplay。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值