Unity ECS System在什么时候更新?怎么自定义这个更新的机遇?
在什么时候更新?
在其他用户代码都履行完之后。
去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
别离取得InitializationSystemGroup
,SimulationSystemGroup
和PresentationSystemGroup
;然后作为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界面里就看不到了,也算是一个小缺陷吧。