Unity ECS(五)了解System执行顺序
view 2196
2019-11-21
E
EntherVarope
Electronic Arts-Leader Programmer
了解一个框架最好的途径之一就是从它的执行顺序入手。
(这里做一个勘误,在https://connect.unity.com/p/unityecs-san-helloworld-ecs-2中SpawnCubeSystem的[UpdateInGroup(typeof(SimulationSystemGroup))]标签应该为[UpdateInGroup(typeof(InitializationSystemGroup))])虽然就结果上来说没什么区别,但是在ECS流程上是错误的)
在前文中,我提到了System是由World来管理的,但是World是怎么知道System的执行顺序的?为什么在我们的HelloWorld程序中,World就知道应该是先创建方块,然后再让方块进行噪波运动的?这其中难道是有什么玄学的魔法吗?现在就来了解这其中的机制!
还记得我提到过的Entity Debugger窗口吗,这是个十分重要的窗口,希望你能尽早掌控它:
运行HelloWorld程序,在EntityDebugger窗口内查看:
有三个窗口,分别管理System,Entity,MemoryChunk
如果你不是在DefaultWorld上,请切换到DefaultWorld,并折叠System下的所有分支,那么你会得到上图的结果。这就是ECS框架中最基本的流程。
在ECS中,World通过一种名为ComponentSystemGroup的系统组来管理System的执行程序。
Component System Groups(组件系统组)
Component System Groups其实是为了解决World中各种 update 的顺序问题。一个系统组中包含了很多需要按照顺序一起 update 的组件系统component systems,可以来指定它成员系统member system的 update 顺序。
Unity提供了三种基本的ComponentSystemGroup
展开一级,你会看到如下几个ComponentSystemGroup,他们的职能一目了然
1.
InitializationSystemGroup 负责初始化工作
2.
SimulationSystemGroup 负责逻辑运算工作
3.
PresentationSystemGroup 负责结果与图形渲染工作
这三个ComponentSystemGroup是Unity官方预先提供好的。
再次展开,你就能看到最终我们的HelloWorld程序在实际工作中的执行顺序:
完整的System执行流程
这里将阐述一下ComponentSystemGroup是如何安排我们的系统流程的:
ComponentSystemGroup也被视为“系统”(它也继承ComponentSystem),因此也包含可以调用或是重写的OnUpdate()并且自身也能被添加到World里。
但是,它可以包含任何数量的System(甚至可以嵌套包含ComponentSystemGroup),World会让它调用自身的OnUpdate()来执行包含的System,每一个ComponentSystemGroup都可以重写SortSystemUpdateList()方法来对包含的System执行顺序进行排序,你也可以自己重写来设计你专属的ComponentSystemGroup与专属的排序方法,但是除非你的程序需求是十分“别具一格”的(比如自己实现FixedUpdate()),不然官方提供的这三个ComponentSystemGroup足以满足大部分流程需要,除此之外这三个系统组还做了一系列的工作(例如初始化渲染)为ECS工作铺好了路,所以最好不要去更改其中的内容。
关于Unity提供的这三个基础的ComponentSystemGroup以及它们是如何参与到World中的,可以在IDE内参考DefaultWorld.cs和DefaultTinyWorldInitialization.cs,World.cs这三个文件,不用关心其他的代码,只需要关注这三个文件关于System与ComponentSystemGroup的代码。
接下来就是排序了:
使用SystemGroup.SortSystemUpdateList(),组中的每个系统将按以下原则进行排序:
根据其[UpdateBefore/After(typeof(MySystem))]属性。如果在进行排序时在同一组中找不到属于此属性的系统类型,则它无效,并且会向您发送警告。
如果没有[UpdateBefore/After],它将会尝试分配到合适的位置,但仍确保那些具有[UpdateBefore/After]属性的System顺序不会改动。
如果该ComponentSystemGroup包含另一个ComponentSystemGroup,则将对其进行递归排序。
它可以检测到您的循环依赖关系[UpdateBefore/After]并记录信息。
(注:Unity ECS提供的三个基本ComponentSystemGroup是固定的执行顺序,你可以在World.cs文件中最下方找到对它们进行处理的方法)
World.cs
........... public void Update() { InitializationSystemGroup initializationSystemGroup = GetExistingSystem(typeof(InitializationSystemGroup)) as InitializationSystemGroup; SimulationSystemGroup simulationSystemGroup = GetExistingSystem(typeof(SimulationSystemGroup)) as SimulationSystemGroup; PresentationSystemGroup presentationSystemGroup = GetExistingSystem(typeof(PresentationSystemGroup)) as PresentationSystemGroup; initializationSystemGroup?.Update(); simulationSystemGroup?.Update(); presentationSystemGroup?.Update(); }
结合HelloWorld程序,设计的两个System将是以这样的方式进入ComponentSystemGroup内的
现在来做几个小实验,编写两个脚本SequenceSystemA,SequenceSystemB分别在不同的系统组内运行
[UpdateInGroup(typeof(InitializationSystemGroup))] public class SequenceSystemA : ComponentSystem { protected override void OnUpdate() { Debug.Log("SequenceSystemA Updating"); } }
[UpdateInGroup(typeof(SimulationSystemGroup))] public class SequenceSystemB : ComponentSystem { protected override void OnUpdate() { Debug.Log("SequenceSystemB Updating"); } }
可以看到两个System如期在我们指定的系统组内运行
试着把标签改为
[UpdateInGroup(typeof(SimulationSystemGroup))] [UpdateAfter(typeof(SequenceSystemB))] public class SequenceSystemA : ComponentSystem { protected override void OnUpdate() { Debug.Log("SequenceSystemA Updating"); } }
[UpdateInGroup(typeof(SimulationSystemGroup))] public class SequenceSystemB : ComponentSystem { protected override void OnUpdate() { Debug.Log("SequenceSystemB Updating"); } }
如果一切顺利,你现在就有基本的能够控制System执行顺序的能力了,试着去进行不同的顺序组合,或者熟读上文提到的三个脚本(DefaultWorld.cs、DefaultTinyWorldInitialization.cs、World.cs)会有十分大的帮助。
扩展
在EntityDebugger窗口内将查看视图中的ShowFullPlayerLoop 你就能看到完整的程序流程,大多这些流程都是固定的潜伏在表层之下的内部组件的工作流。试着在这几个系统组内编写你的System。
Unity ECS官方手册
https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/index.html
Recommended reading
Unity ECS(五)了解System执行顺序
EntherVarope
2019-11-21
view 2196
yes icon
Unity ECS(四)ECS组成概念
EntherVarope
2019-11-19
view 2133
yes icon
Unity ECS(三)HelloWorld!ECS!(2)
EntherVarope
2019-11-13
view 2839
yes icon
Unity ECS(一)了解ECS与DOTS
EntherVarope
2019-11-7
view 3335
yes icon
Unity ECS 前言
EntherVarope
2019-11-4
view 1950
yes icon
Unity ECS(二)HelloWorld!ECS!(1)
EntherVarope
2019-11-12
view 2594
yes icon
Open In App