天天看点

ECS、Job和Burst——创建实体

由Unity官方推荐,想要在Unity中做出高性能的游戏场景,需要用到Unity2018推出的ECS系统,但是现在已经有2019了,ECS依然还是预览版,这就意味着整个ECS系统还会有很多变化,所以这篇文章仅供参考。

本文翻译的是官方提供的文档,并加入自己的一部分理解。

安装Unity ECS系统

首先,要使用ECS,需要在Unity/Window/Packag Mananger中选取Advanced/Show preview packags。(注意:有些人会无限刷新无法获取预览版的packags,需要设置网络为自动获取DNS)然后选择Entities,选择Install。

ECS、Job和Burst——创建实体

Enitities已包含Burst和Jobs,有些时候这些不同的包在Package Mnanager中的版本比在Entities中高,所以有需要请自己更新。

另外,如果需要使用Entities创建实体的3D物体,还需要导入Hybrid Renderer包,这个包提供的结构体是渲染3D物体需要用到的,当然也可以自己定义包含渲染所需数据的结构体。按照说明还有LOD相关的东西。

ECS、Job和Burst——创建实体

使用EntityManager创建实体

Entities是实体组件系统体系结构的三个主要元素之一。它们代表了游戏或程序中的单个“事物”。一个实体既没有行为也没有数据;相反,它标识哪些数据片段属于一起。 Systems提供行为。 Components存储数据。

实体本质上是一个ID。您可以将其视为一个超轻量级的GameObject,它甚至在默认情况下没有名称。实体ID是稳定的。它们是存储对另一个组件或实体的引用的唯一稳定方法。

EntityManager管理World中的所有实体。EntityManager维护实体列表,并组织与实体关联的数据,以获得最佳性能。

尽管实体没有类型,但是可以根据与实体关联的数据组件的类型对实体组进行分类。当您创建实体并向其添加组件时,EntityManager将跟踪现有实体上组件的独特组合。这种独特的组合称为原型。在向实体添加组件时,EntityManager创建一个EntityArchetype结构体。您可以使用现有的entityprototype创建符合该原型的新实体。您还可以预先创建entityprototype并使用它创建实体。

创建实体的最简单方法是在Unity编辑器中。您可以设置场景中的GameObjects或者运行时实体化的Prefabs。对于游戏或程序中更动态的部分,您可以在Job中创建多个实体的生成系统(使用创建多个实体的方法)。最后,您可以使用EntityManager.CreateEntity每次创建一个实体。

使用 EntityManager.CreateEntity 函数可以创建实体。所有使用创建的实体与EntityManager在同一个世界中。

您可以通过以下方式逐一创建实体:

  • 使用ComponentType对象数组创建带有组件的实体。
  • 使用EntityArchetype创建包含组件的实体。
  • 使用Instantiate复制现有实体,包括其当前数据。
  • 创建没有组件的实体,然后向其添加组件。(您可以立即添加组件,也可以根据需要添加其他组件。)

您还可以在同一时间创建多个实体:

  • 使用CreateEntity用具有相同原型的新实体填充NativeArray。
  • 使用 Instantiate用现有实体(包括其当前数据)的副本填充NativeArray。
  • 使用CreateChunk显式创建包含指定数量的实体和给定原型的块。

创建实体之后,您可以添加或删除组件,当您这样做时,受影响实体的原型将发生更改,EntityManager必须将更改后的数据移动到新的内存块,并将组件数组压缩到原始块中。

对导致结构更改的实体的更改——即添加或删除组件,更改SharedComponentData的值,以及销毁实体——不能在Job中执行,因为这会使Job正在处理的数据失效。相反,您可以使用 EntityCommandBuffer添加命令来进行这些类型的更改,它会在Job完成后执行这个缓冲区中的命令。

EntityManager提供了从单个实体以及NativeArray中的所有实体中删除组件的功能。更多信息,请参见Components 。

迭代具有一组匹配组件的所有实体是ECS体系结构的核心。参见访问实体数据。

World

一个World同时拥有一个 EntityManager和ComponentSystems。您可以创建任意多个World对象。通常,您会创建一个模拟世界(simulation 

World

)和呈现或表示世界( rendering or presentation 

World

)。

默认情况下,我们在进入播放模式时创建一个单独的世界,并用项目中所有可用的ComponentSystem对象填充它,但是您可以禁用默认的世界创建,并通过全局定义用您自己的代码替换它。

  • Default World creation code (see file: Packages/com.unity.entities/Unity.Entities.Hybrid/Injection/DefaultWorldInitialization.cs)
  • Automatic bootstrap entry point (see file:Packages/com.unity.entities/Unity.Entities.Hybrid/Injection/AutomaticWorldBootstrap.cs)

World可以使用new World(string name)创建出来,但是这样的World并没有运行

ECS、Job和Burst——创建实体
ECS、Job和Burst——创建实体

从上图可以看出,直接New出来的World缺少了很多东西。

有能力的自己去看源码修改吧。

继续阅读