Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

How do you update your systems instantly in Edit Mode?

Discussion in 'Data Oriented Technology Stack' started by bac9-flcl, Dec 17, 2018.

  1. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    777
    If a world is bootstrapped in the editor (through something like DefaultWorldInitialization of GameObjectEntity), it receives regular updates about every two seconds with the following stack:

    Code (csharp):
    1. (...) :OnUpdate() (at Assets/(...) .cs:(...))
    2. Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/ComponentSystem.cs:375)
    3. Unity.Entities.ScriptBehaviourManager:Update() (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/ScriptBehaviourManager.cs:77)
    4. Unity.Entities.DummyDelagateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/ScriptBehaviourUpdateOrder.cs:703)
    There is only one thing that instantly triggers it, and I'm not sure why - resizing a viewport like Scene view. Anyway, what I'd like to do is trigger an update manually - because spawning or destroying an entity and then waiting for two seconds until Entity Debugger and all my systems like rendering receive a tick is not a nice user experience.

    And smooth editor UX aside, there is a bigger problem which can arise from Entity Manager and everything else not receiving updates immediately: if you attempt to create or destroy entities returned by EntityManager multiple times without a single player loop tick happening inbetween, you eventually break the entity system due to entities somehow breaking Exists function.

    Code (csharp):
    1. ArgumentException: All entities passed to EntityManager must exist. One of the entities has already been destroyed or was never created.
    2. Unity.Entities.EntityDataManager.AssertEntitiesExist (Unity.Entities.Entity* entities, System.Int32 count) (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/EntityDataManager.cs:326)
    3. Unity.Entities.EntityManager.AddComponent (Unity.Entities.Entity entity, Unity.Entities.ComponentType type) (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/EntityManager.cs:386)
    4. Unity.Entities.EntityCommandBuffer.PlaybackChain (Unity.Entities.EntityManager mgr, Unity.Entities.ECBSharedPlaybackState& playbackState, Unity.Collections.NativeArray`1[T] chainStates, System.Int32 currentChain, System.Int32 nextChain) (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/EntityCommandBuffer.cs:971)
    5. Unity.Entities.EntityCommandBuffer.Playback (Unity.Entities.EntityManager mgr) (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/EntityCommandBuffer.cs:872)
    6. Unity.Transforms.TransformSystem.UpdateDAG () (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Transforms/TransformSystem.cs:353)
    7. Unity.Transforms.TransformSystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Transforms/TransformSystem.cs:1151)
    8. Unity.Entities.JobComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/ComponentSystem.cs:508)
    9. Unity.Entities.ScriptBehaviourManager.Update () (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/ScriptBehaviourManager.cs:77)
    10. Unity.Entities.ScriptBehaviourUpdateOrder+DummyDelagateWrapper.TriggerUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.21/Unity.Entities/ScriptBehaviourUpdateOrder.cs:703)
    So its not just a matter of Entity Debugger lagging behind by two seconds, lack of updates landing in Edit mode often enough is a potentially breaking problem. Initially, I assumed that player loop could be updated in edit mode manually, and all you had to do was call this:

    Code (csharp):
    1. ScriptBehaviourUpdateOrder.UpdatePlayerLoop ();
    But it seems to have no relevant effect. What should I call, then?
     
    Last edited: Dec 18, 2018
  2. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    777
    Found the right method, part of the relatively recently added player loop API:

    Code (csharp):
    1. UnityEditor.EditorApplication.QueuePlayerLoopUpdate ();
    Calling this indirectly triggers updates on every system, there is no need to manually get them from a world and update each.