All system stopped running except MeshInstanceRendererSystem

I just try upgrading to 2018.3.0b2 in order to use the new prefab system and upgraded Entities to preview 15, after all the fixes about .Concurrent needing job index and thing about zero-sized components I am able to run the game, but now all of my systems in the debugger has 0.00 time except MeshInstanceRendererSystem which the number is running.

All of them seems to have the entities required for OnUpdate activation as seen on the right hand side of the debugger but OnUpdate does not activate at all. What could be the possible problem here? (Even a system with no injects which should always run does not run with perfectly constant 0.00ms)

You should check ‘RenderingSystemBootstrap.cs’.
It registers rendering delegate to camera event handler.

Ah… I know what’s happening now. I have recently installed UniRx.Async. They have something like this :

        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        static void Init()
        {
            // capture default(unity) sync-context.
            unitySynchronizationContetext = SynchronizationContext.Current;
            mainThreadId = Thread.CurrentThread.ManagedThreadId;

            if (runners != null) return; // already initialized

            var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
            Initialize(ref playerLoop);
        }

It has the same RuntimeInitializeLoadType.BeforeSceneLoad and this one runs after ECS’s bootstrap, overriding the player loop with a default one + some modifications completely. (So all prepared systems disappeared, what’s remaining is exactly because ‘RenderingSystemBootstrap.cs’ callback is independent of PlayerLoop) The ordering is not guaranteed according to Unity docs, so there is no way to “win” over ECS’s bootstrap reliably.

Also, it is a shame that this PlayerLoop API does not include how to get the current player loop (why not?) just default and set. If that is so any RuntimeInitializeOnLoadMethod that runs later can work on the loop in continuation from the prior one, without knowing about prior one. The only way now is that this library needs to know about Unity.Entities and grab the ECSified PlayerLoop via ScriptBehaviourUpdateOrder.CurrentPlayerLoop.

(This public static field for safekeeping the PlayerLoop seems to acknowledge that getting the current PlayerLoop is not possible, either only currently or technically?)

ScriptBehaviourUpdateOrder.CurrentPlayerLoop.

you can manually active all your systems

ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.Active);

That won’t work. Imagine it goes like this :

Enter play mode.

DefaultWorldInitialization > ScriptBehaviourUpdateOrder.UpdatePlayerLoop

  • Get default player loop then make it includes all systems in all specified worlds.
  • Set that player loop as active with PlayerLoop.SetPlayerLoop
  • That modified player loop is stored in ScriptBehaviourUpdateOrder : public static PlayerLoopSystem CurrentPlayerLoop;
  • Some other ECS code are reading from this CurrentPlayerLoop static property, it is also open for anyone to use.

UniRx or other libraries RuntimeInitializeOnLoadMethod with player loop modification

  • Get default player loop and make some modifications. Other libs has no knowledge of ECS ScriptBehaviourUpdateOrder.CurrentPlayerLoop. (nor it is guaranteed to run before or after ECS’s modification)
  • The player loop now is that of the default plus some modifications, but without any systems from the ECS bootstrap.

Call ScriptBehaviourUpdateOrder.UpdatePlayerLoop manually

  • Get default player loop then make it includes all systems in all specified worlds.
  • Then the same happen, but this time those modifications from other libs will disappear.

Rather than having to store the current player loop externally the player loop API needs to be able to return the current loop for anyone to build additively on it. There is a chance that ECS will not be the only one that needs to modify the player loop in the future.

1 Like

Here is the solution about UniRx.
http://notargs.hateblo.jp/entry/ecs_unirx

After the timing of RuntimeInitializeLoadType.BeforeSceneLoad
You should re-Initialize UniRx playerloop with ECS playerloop.

var playerLoop = ScriptBehaviourUpdateOrder.CurrentPlayerLoop;
PlayerLoopHelper.Initialize(ref playerLoop);
4 Likes

For the future readers, UniRx patched this, but if you’ve encountered this on 2019.3+ there’s no ScriptBehaviourUpdateOrder.CurrentPlayerLoop anymore.

So to fix this issue, go to PlayerLoopHelper.cs in UniRx.Async, and replace var playerLoop with the following:

            var playerLoop =
#if UNITY_2019_3_OR_NEWER
                PlayerLoop.GetCurrentPlayerLoop();
#else
                PlayerLoop.GetDefaultPlayerLoop();
#endif

Or just… update UniRx