Unity Data Oriented Tech Stack
What is the Unity Data Oriented Tech Stack
Unity正在制作一个新的高性能多线程的系统,来让游戏能够充分利用多核性能,避免很重的编程头疼问题。DOTS包含以下主要系统:
Entity Component System 提供了写高校代码的方式 C# Job System 让游戏并行在多核CPU上 Burst Compiler 新的数学感知的后端编译器,可以产生高度优化的机器代码
通过这些系统,Unity可以为你的平台提供高度优化的代码。更多信息
2019.3 DOTS Samples
Unity提供了示例项目,可以通过这个项目来学习怎么写DOTS的游戏。
这个新的框架要求我们忘掉对象(object)概念,而专注于数据(data,component)本身该怎么去被处理。系统(ystem)把数据从输入状态转成输出状态。 系统读取了位置和旋转Component,把他们相乘,然后更新LocalToWorld Component. 虽然A和B有Renderer Component,而C没有,但是这并不影响系统。系统根本不关心Renderer。
Archetypes
一个独一无二的Component组合叫做Archetype(原型)。例如,一个3D实体应该有一个Component表示它的世界位置,一个Component表示它的线性移动,一个表示旋转,一个表示视觉表现。既然他们都有相同的组件,那就可以把他们定义成一个Archetype。 你可以在运行时改变实体所拥有的Component,比如当你从A移除Renderer,A就变成了Arthetype N.
Memory Chunks
实体的原型决定了这个实体在哪存储。ECS在Chunks里申请内存,每一个都代表了一个ArchetypeChunk实体。一个块(chunk)总是包含了某一种原型的数个实体.当一块内存满了,就会申请一新块来存储同样原型的实体。如果你对一个实体增减component,从而改变它的原型,那这个实体会被移到另一个块里。 这种组织方案在原型和块间提供了一个一对多的关系。这意味着搜索相同原型实体时非常迅速。 当一个实体移出时,这个块的最后一个实体会被移到空出来的位置。而实体会移入拥有空位的第一个块。 注意,原型中共享组件的值还决定了哪些实体存在哪个块中。拥有相同值共享组件的实体会被存在同一个块里。如果修改值,那它会被移出,就像改原型一样。详见RenderMesh component。
Entity queries
我们通过entity queries来查询一个系统应该处理哪些实体。它会搜索所有的已有原型,匹配满足你需求的实体们。All-原型必须包含所有组件,Any-原型至少包含一个组件, None-原型必须不包含任何一个组件。请求会返回一个chunks列表。之后可以通过IJobChunk, IJobForEach, non-Jobfor-each loop轮询所有components。
Jobs
你可以使用Jobs来充分发挥多线程的能力。ECS提供JobComponentSystem,和特化的Jobs类型,IJobForEach和IJobChunk,来在主线程之外传输数据。IJobForEach是典型的最易于使用的。IJobChunk处理更复杂的情况。 Jobs使用EntityQuery不仅定义哪些组件需要获取,还要确定权限是只读还是只写。这些读写权限让系统知道哪些任务可以并行哪些得串行。Jobs读取同样的数据可以同时跑,但是如果要写别的任务需要的数据,这样的任务就要一个一个跑。 而需要串行的任务按什么顺序跑,取决于你定义的任务依赖。当核心ECS代码跑OnUpdate方法时,它传了JobHandle参数,封装了已经存在的任务依赖。当你安排一个任务,Job Schedule()方法返回一个新的JobHandle,包括了新的依赖。
System organization
ECS通过World和group组织systems。默认情况下,ECS创建一个默认World和一些预设的groups。它会找到所有可用的systems,初始化他们,把他们加入到预设的sumulation group。 你可以设定同组内系统的更新顺序。一个Group 本身也是一种系统,所以你能把一个group加入另一个group,并且设定他的顺序。一个group里的所有system都会在下一个group之前更新完。如果你没有指明一个顺序,系统会以确定的方式插入更新,而不依赖创建顺序。换言之,同样一组systems总是以同样的顺序运行。 Systemy updates发生在主线程。但是系统可以用Jobs来卸载工作,到额外的线程。Jobs提供了直截了当的方式来创建和调度任务。
ECS Authoring
当在unity编辑器创建你的游戏时,你可以用GameObjects和MonoBehaviors,创建转换系统来对应Unity objects和components到entities。这段我实在不会翻译了,建议看原文。