Unity ECS System在什么时候更新?如何自定义这个更新的时机?
  VzZBtB0KXYfE 2024年08月07日 44 0

在什么时候更新?

在其他用户代码都执行完之后。

去Netcode的ClientServerBootstrap里可以找到CreateLocalWorld函数,里面有类似这样的代码:

public static World CreateLocalWorld(string defaultWorldName = "Default World")
{
    var world = new World(defaultWorldName, WorldFlags.Game);

    var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
    DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
    ScriptBehaviourUpdateOrder.AppendWorldToCurrentPlayerLoop(world);

    return world;
}

其中ScriptBehaviourUpdateOrder.AppendWorldToCurrentPlayerLoop就是将World更新附加到UnityEngine.LowLevel.PlayerLoop后面的函数。这个函数内容也很简单,本质上是通过world.GetExistingSystemManaged分别获得InitializationSystemGroupSimulationSystemGroupPresentationSystemGroup;然后作为PlayerLoopSystem的SubSystem,构造出新的PlayerLoop之后,通过PlayerLoop.SetPlayerLoop应用到当前环境里。

没有Netcode的情况下也是类似的,只不过是通过DefaultWorldInitialization这个类来完成了。

如何自定义?

知道在哪里创建的,自然就知道该怎么自定义了。只要把ScriptBehaviourUpdateOrder.AppendWorldToCurrentPlayerLoop换成自己的东西就行了。比如:

var initGroup = world.GetExistingSystemManaged<InitializationSystemGroup>();
var simGroup = world.GetExistingSystemManaged<SimulationSystemGroup>();
var presGroup = world.GetExistingSystemManaged<PresentationSystemGroup>();

//找个地方调用initGroup.Update()
//找个地方调用simGroup.Update()
//找个地方调用presGroup.Update()
//顺序不要搞错了

以FishNet为例,就可以在TimeManager.OnPostTick里运行所有WorldSystemFilterFlags.ServerSimulation的System,于是这些基于GameObject的网络库也就可以用ECS设计模式了。
不过自定义了更新之后,在Editor的Systems界面里就看不到了,也算是一个小缺点吧。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年08月07日 0

暂无评论

推荐阅读
  1wMBnbixARwC   2024年08月07日   46   0   0 游戏开发
  NiD7Hlfm86HK   2024年08月07日   51   0   0 游戏开发
  vWa2lMmTbsfJ   2024年08月07日   86   0   0 游戏开发
  PfEVswrG0sbF   2024年08月07日   49   0   0 游戏开发
  1wMBnbixARwC   2024年08月07日   61   0   0 游戏开发
VzZBtB0KXYfE