Unity ECS(五)了解System执行顺序

了解一个框架最好的途径之一就是从它的执行顺序入手。

(这里做一个勘误,在第三篇中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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值