Search Unity

Systems are not updating automatically

Discussion in 'Entity Component System' started by Jay-Pavlina, Dec 16, 2018.

  1. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    What do I have to do to get update to be called on systems? It is only called if I manually call it.

    Code (CSharp):
    1. public sealed class TestComponentSystem : ComponentSystem {
    2.         protected override void OnStartRunning() {
    3.             base.OnStartRunning();
    4.             Debug.Log("OnStartRunning");
    5.         }
    6.  
    7.         protected override void OnStopRunning() {
    8.             base.OnStopRunning();
    9.             Debug.Log("OnStopRunning");
    10.         }
    11.  
    12.         protected override void OnCreateManager() {
    13.             base.OnCreateManager();
    14.             Debug.Log("OnCreateManager");
    15.         }
    16.  
    17.         protected override void OnDestroyManager() {
    18.             base.OnDestroyManager();
    19.             Debug.Log("OnDestroyManager");
    20.         }
    21.  
    22.         protected override void OnUpdate() {
    23.             Debug.Log("OnUpdate");
    24.         }
    25.     }
    Only OnCreateManager() is called. If I call Update(), it calls OnStartRunning() and OnUpdate(), but I thought Update() was supposed to be called automatically.
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    It called automatically if system registred in default world bootstrap ScriptBehaviourUpdateOrder. All depend on how you create this system.
     
  3. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    1,011
    If the system has no matched entities, OnUpdate() is not called when the system uses ComonentGroup. Use [AlwaysUpdateSystem] attribute.
     
  4. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    How can I make sure it is registered? I am not manually creating the system.
    I added the attribute and it is still not being called.

    I added another system and several entities with matched components and it has the same issue. It works when I manually call update, but is not called automatically.

    Code (CSharp):
    1. public sealed class ApplyVelocityToPositionUnitySystem : JobComponentSystem {
    2.         [BurstCompile]
    3.         struct Job : IJobProcessComponentData<Position, Velocity2DComponentData> {
    4.             public float deltaTime;
    5.          
    6.             public void Execute(ref Position position, [ReadOnly] ref Velocity2DComponentData velocity) {
    7.                 var addition = velocity.value * deltaTime;
    8.                 position.Value.x += addition.x;
    9.                 position.Value.y += addition.y;
    10.             }
    11.         }
    12.  
    13.         protected override JobHandle OnUpdate(JobHandle inputDeps) {
    14.             var job = new Job() { deltaTime = Time.fixedDeltaTime };
    15.             return job.Schedule(this, inputDeps);
    16.         }
    17.     }
     
  5. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
    upload_2018-12-17_10-29-46.png

    Your code works fine for me. Has to be something else going on in your project.
     
  6. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    I was able to fix it by manually calling
    ScriptBehaviourUpdateOrder.UpdatePlayerLoop(world);

    Is it normal to have to do that? Maybe something in my project is interfering with ECS. It is a big project.
     
  7. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,759
    You only need to call UpdatePlayerLoop if you're manually adding/removing systems. But it's certainly required if you are.
     
  8. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    I am not, but it's good to know because I would prefer to add the systems manually. I will use Zenject dependency injection for creating them.
     
  9. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Are you using UniRx.Async? That library modifies the player loop in order to make `await` returns to the same spot in the next update etc. It execute after ECS's modification, so all ECS systems are erased from the player loop.

    https://notargs.hateblo.jp/entry/ecs_unirx
     
  10. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Only if you manually operate with system lifetime. You use UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP in Scripting Define Symbols? Or UniRx as @5argon says?
     
  11. Jay-Pavlina

    Jay-Pavlina

    Joined:
    Feb 19, 2012
    Posts:
    195
    Yes, that was the issue. Thanks for the link too.