Search Unity

Proper Way to Shut Down Systems

Discussion in 'Entity Component System' started by AndesSunset, Feb 14, 2019.

  1. AndesSunset

    AndesSunset

    Joined:
    Jan 28, 2019
    Posts:
    60
    I've recently been experimenting with a manual system loop. I still have one parent system which is part of Unity's auto-generated loop. That system then holds references to other, child systems. It creates them in
    OnCreateManager()
    , manually updates them in
    OnUpdate()
    , and destroys them (using
    World.DestroyManager<T>()
    ) in
    OnDestroyManager()
    .

    But I noticed recently that my systems are still being updated in the editor, after game mode has stopped running.

    I haven't had much time to dig into this, but what could I be doing wrong here? Is there a proper way to shut systems down that I'm not doing?

    P.S.

    I'm calling
    World.CreateManager<T>()
    to create my child systems, but I never call
    ScriptBehaviourUpdateOrder.UpdatePlayerLoop()
    after creating them. Reason: I assume that would cause Unity to add and order them in the player loop. I'm only using
    CreateManager()
    so that those systems can make use of ComponentGroups and ShouldRun().

    For that reason, I"m also not calling
    UpdatePlayerLoop()
    After I destroy those child systems. Should I be?
     
  2. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
    Deviating from the question a little bit: What is the reason you decided to go with a manual system loop? Just as a learning experience or do you think it would be superior to Unity's internal loop?
     
  3. AndesSunset

    AndesSunset

    Joined:
    Jan 28, 2019
    Posts:
    60
    I needed to run some of my systems more than once per frame in a looping fashion, which Unity’s auto-generated loop doesn’t currently support. :)

    However, the ECS team is currently reworking the system loop code, and there are comments in the source that mention having multiple instances of a system type. So who knows what the future may hold.

    I’m not holding my breath for officially supported looping behavior, though. :p
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    I don't get this either. It keeps popping up and it seems like a really stupid idea. I reckon a good 1/4 of the issues that are posted on this forum now are caused by people running their own loops...

    Look at the RenderMeshSystem. It runs 1 time per camera, so if you have 4 cameras in a scene it'll run 4 times per loop. This is a much better approach than butchering the entire loop.
     
  5. AndesSunset

    AndesSunset

    Joined:
    Jan 28, 2019
    Posts:
    60
    Please stick to the OP topic, tertle.
     
  6. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
    Oh, I see, it makes sense. Perhaps you should go with a completely standalone ECS framework? That may be easier to implement.
     
    AndesSunset likes this.
  7. AndesSunset

    AndesSunset

    Joined:
    Jan 28, 2019
    Posts:
    60
    You mean not use any of Unity’s ECS framework? It’s possible, but it probably shouldn’t be neccessary. Unity’s own FPS Sample project recently chose not to use the auto-generated ECS loop in their code, and their systems shut down correctly.

    Back in 2018 Joachim commented on these forums that Updating one system from another (to solve a similar problem) should be a fine pattern. Granted, things can change around here. I look forward to learning about their rewrites :)
     
    Last edited: Feb 14, 2019
    starikcetin likes this.
  8. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    First of all your behaviour incorrect. If your Initital system created automatically (you not use DeisableAutoCreation) and you call CreateManager for other systems in OnCreateManager, even if thes system has DisableAutoCreation, they will be in default player loop. For example:
    This initial system which created automatically, and as you can see just creates 2 other systems in OnCreate
    Code (CSharp):
    1. public class SimpleSample : JobComponentSystem
    2. {
    3.     private FirstSystem first;
    4.     private SecondSystem second;
    5.    
    6.     protected override void OnCreateManager()
    7.     {
    8.         Debug.Log("---------Create Initial------");
    9.         first = World.CreateManager<FirstSystem>();
    10.         second = World.CreateManager<SecondSystem>();
    11.     }
    12.    
    13.     protected override void OnDestroyManager()
    14.     {
    15.         Debug.Log("---------Destroy Initial------");
    16.     }
    17.  
    18.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    19.     {
    20.         Debug.Log("---------Initial------");
    21.         first.Update();
    22.         second.Update();
    23.         Debug.Log("---------------");
    24.         return inputDeps;
    25.     }
    26. }
    First and Second manual created systems
    Code (CSharp):
    1. [DisableAutoCreation]
    2. public class FirstSystem : JobComponentSystem
    3. {
    4.     protected override void OnCreateManager()
    5.     {
    6.         base.OnCreateManager();
    7.         Debug.Log("---------Create First------");
    8.     }
    9.  
    10.     protected override void OnDestroyManager()
    11.     {
    12.         base.OnDestroyManager();
    13.         Debug.Log("---------Destroy First------");
    14.     }
    15.  
    16.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    17.     {
    18.         Debug.Log("First");
    19.         return inputDeps;
    20.     }
    21. }
    Code (CSharp):
    1. [DisableAutoCreation]
    2. public class SecondSystem : JobComponentSystem
    3. {
    4.     protected override void OnCreateManager()
    5.     {
    6.         base.OnCreateManager();
    7.         Debug.Log("---------Create Second------");
    8.     }
    9.  
    10.     protected override void OnDestroyManager()
    11.     {
    12.         base.OnDestroyManager();
    13.         Debug.Log("---------Destroy Second------");
    14.     }
    15.  
    16.     protected override JobHandle OnUpdate(JobHandle jh)
    17.     {
    18.         Debug.Log("Second");
    19.         return jh;
    20.     }
    21. }
    And if you hit play you'll see First and Second systems in EntityDebugger, because they are in player loop (entity debugger use player loop for show systems and if system not in player loop you can't see that). And if you look at debug log you'll see that systems call twice - once from SimpleSample Update, and once from their OnUpdate by PlayerLoop. upload_2019-2-15_10-36-1.png
     
    starikcetin likes this.