Categories

Tags

Table of Contents

  1. 实体
  2. 实体的创建
    1. 通过EntityManager创建实体
    2. 添加和移除组件
    3. 遍历实体对象
  3. World

实体

实体(Entity) 是 ECS架构中的三大概念中的一个,另外两个分别是组件(Component)和系统(System)。实体表示游戏中的各个”事物”,实体并不包含任何行动或者数据,它只是标识了哪些数据是一起的,属于同一个事物的。系统则提供行为,组件是用来保存数据。

实体的本质就是一个ID,你可以把它当成一个连默认名称都没有的超级轻量级GameObject。实体ID是可靠的,你可以用它来保存其它组件或者实体的引用。例如,在层次结构中的子实体可能需要引用其父实体。

EntityManager 管理者World中的所有实体。EntityManager管理着实体列表并且组织和实体关联的数据以获得最佳的性能。

尽管实体没有类型数据,可以按照与实体关联的组件的类型来给一组实体进行分类。当你创建实体并给它添加组件时,EntityManager会追踪现有所有实体上组件的唯一组合,这种唯一的组合被称为原型(Archetype)。当你添加组件给实体时,EntityManager就会尝试创建一个EntityArchetype结构体。你也可以使用一个已存在的EntityArchetype来创建符合该原型的实体。你还可以预先创建一个EntityArchetype,然后在需要的时候用它来创建实体。

实体的创建

最简单的创建实体的方式,就是在Unity 编辑器中,你可以和平常一样在场景中放置游戏对象以及创建预制体,然后再运行的时候把它们转为实体。对于游戏中那些更加动态的部分,你可以创建生成系统,以在Job中来创建多个实体对象。最后,你可以使用EntityManager.CreateEntity函数来创建实体。

通过EntityManager创建实体

使用EntityManager.CreateEntity函数来创建单个实体,实体的World和所使用的EntityManager相同。 你可以通过以下方法逐个创建实体

  • 通过一组ComponentType来创建一个拥有这些组件的实体
  • 通过原型(Archetype)来一个拥有某些组件的实体
  • 通过Instantiate来拷贝一个现存实体,包括它当前的数据
  • 先创建一个没有任何组件的实体,然后再给它添加所需的组件(你可以马上给它添加组件,或者在需要的时候再给他添加)

你也可以一次性添加多个实体

  • 使用CreateEntity函数,来将NativeArray填充为相同原型的实体
  • 使用Instantiate,用一个现存实体的拷贝来填充NativeArray
  • 使用CreateChunk,通过给定原型和数量来明确的创建一个块。(前面的两个方法,Unity会在背后默认为我们创建Chunk)

添加和移除组件

创建完一个实体后,你可以添加或移除它的组件,当你做做这些操作时,该实体所对应的原型发生了改变(即这个实体不在符合该原型),因此EntityManager必须把这些变动的数据移动到一个新的块,并且压缩原块中的组件数组。

对一个实体对象的更改会导致结构的更改——即添加或删除组件 改变了SharedComponnetData

而销毁一个实体,无法在Job内部完成此操作,因为这个操作可能会使得Job正在处理的数据无效。不过,你可以将这些类型的改变通过添加命令到EntityCommandBuffer,并在Job完成后再执行这个命令缓存

EntityManager提供从单个实体中删除组件,以及从NativeArray中所有实体上删除组件的函数。

遍历实体对象

我们可以遍历一组具有匹配组件的所有实体,具体方法在另一篇文章“实体数据的访问”中再说明

World

一个World 由 EntityManager 和 一组ComponentSystem组成。你可以随意创建一个World对象。一般,你将创建一个World用来仿真模拟,另一个World用来图像渲染。

默认情况下,当我们点击Play按钮时,会创建一个World,并且使用项目中所有可用的ComponentSystem 对象来填充它。不过你可以禁用默认的世界创建,并通过全局定义将其替换为自己的代码

#UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_RUNTIME_WORLD 禁用 默认运行时世界 的生成 #UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_EDITOR_WORLD 禁用 默认编辑器世界 的生成 #UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP 两种世界的生成都禁用

  • 默认World创建代码(Default World creation code) 参考文件: Packages/com.unity.entities/Unity.Entities.Hybrid/Injection/DefaultWorldInitialization.cs
  • 自动引导程序入口(Automatic bootstrap entry point) 参考文件: Packages/com.unity.entities/Unity.Entities.Hybrid/Injection/AutomaticWorldBootstrap.cs