Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[SOLVED] How to Destroy World correctly?

Discussion in 'Entity Component System' started by AGeorgy, Mar 28, 2019.

  1. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    42
    Code (CSharp):
    1. void Start()
    2.     {
    3.         _serWorld = new World("SerWorld");
    4.         _serWorld.CreateManager<MoveJobSystem>();
    5.         ScriptBehaviourUpdateOrder.UpdatePlayerLoop(_serWorld);
    6.        
    7.             //...
    8.             //Create Entities
    9.             //...
    10.     }
    11.  
    12. public void Destroy()
    13.     {
    14.         _serWorld.Dispose();
    15.         ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.Active);
    16.     }
    I got:
    InvalidOperationException: Unity.Entities.SimulationSystemGroup has already been destroyed. It may not be used anymore.
     
    eggsamurai and EvansT like this.
  2. Srokaaa

    Srokaaa

    Joined:
    Sep 18, 2018
    Posts:
    169
    This title wins a reward for best phrased question :p
     
    Mikael-H, NotaNaN, Flurgle and 10 others like this.
  3. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    42
    It's a clickbait :)
     
  4. floboc

    floboc

    Joined:
    Oct 31, 2017
    Posts:
    91
    Did you find the correct way ?
     
  5. floboc

    floboc

    Joined:
    Oct 31, 2017
    Posts:
    91
    Still looking for an answer here, is it possible to have some feedback from the Unity team, please?

    Here is what the error looks like if trying to dispose a world:

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. Unity.Entities.ComponentSystemBase.AfterUpdateVersioning () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:317)
    3. Unity.Entities.ComponentSystem.AfterOnUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:531)
    4. Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:578)
    5. Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:166)
    6. Unity.Entities.ComponentSystemGroup.OnUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystemGroup.cs:361)
    7. UnityEngine.Debug:LogException(Exception)
    8. Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/Stubs/Unity/Debug.cs:25)
    9. Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystemGroup.cs:365)
    10. Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:571)
    11. Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:166)
    12. Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystemGroup.cs:361)
    13. Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:571)
    14. Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:166)
    15. Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ScriptBehaviourUpdateOrder.cs:129)
    16.  
    17.  
    which is followed by this error too:

    Code (CSharp):
    1. InvalidOperationException: Unity.Entities.PresentationSystemGroup has already been destroyed. It may not be used anymore.
    2. Unity.Entities.ComponentSystemBase.CheckExists () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:208)
    3. Unity.Entities.ComponentSystemBase.ShouldRunSystem () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:214)
    4. Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:554)
    5. Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:166)
    6. Unity.Entities.ScriptBehaviourUpdateOrder+DummyDelegateWrapper.TriggerUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ScriptBehaviourUpdateOrder.cs:129)
    7.  
     
  6. EvansT

    EvansT

    Joined:
    Jan 22, 2015
    Posts:
    22
    I'm getting the same error too. Did you find a solution?
     
  7. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    42
    I make this thing. Works to me:
    Code (CSharp):
    1. _world.QuitUpdate = true;
    2. ScriptBehaviourUpdateOrder.UpdatePlayerLoop(null);
    3. // Or this:
    4. // ScriptBehaviourUpdateOrder.SetPlayerLoop(PlayerLoop.GetDefaultPlayerLoop());
    5. _world.EntityManager.CompleteAllJobs();
    6. _world.EntityManager.DestroyAllEntity();
    7. _world.Dispose();
    But it's cheating. I don't remove world in fact.
     
    Last edited: Jun 19, 2019
  8. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,112
    i just tried to destroy a World with a simple :
    Code (CSharp):
    1. if (CachingWorld.IsCreated)
    2.                 CachingWorld.Dispose();
    and it works perfectly no errors.
     
  9. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    42
    It depends
     
  10. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    42
    Solution:
    Code (CSharp):
    1. _world = new World("name");
    2. //... setup
    3. _loopIndexes = _world.AddWorldToPlayerLoop();
    4.  
    5. //...
    6.  
    7. public async void Dispose()
    8.         {
    9.             _world.QuitUpdate = true;
    10.             WorldExtensions.RemoveWorldFromPlayerLoop(_loopIndexes);
    11.             _world.EntityManager.CompleteAllJobs();
    12.            
    13.             await Awaiters.NextFrame;
    14.            
    15.             _world.Dispose();
    16.         }
    Code (CSharp):
    1. public static void RemoveWorldFromPlayerLoop(PlayerLoopTuple loopIndexes)
    2.         {
    3.             var resultPls = new PlayerLoopSystem {subSystemList = new PlayerLoopSystem[ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList.Length]};
    4.            
    5.             for (var i = 0; i < ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList.Length; i++)
    6.             {
    7.                 var sub = ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList[i].subSystemList;
    8.  
    9.                 var resultSub = ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList[i];
    10.                 var tempSub = new PlayerLoopSystem[sub.Length];
    11.  
    12.                 var index = 0;
    13.                 for (var j = 0; j < sub?.Length; j++)
    14.                 {
    15.                     if (sub[j].type == typeof(SimulationSystemGroup) && j == loopIndexes.SimulationIndex)
    16.                     {
    17.                         sub[j].updateDelegate = null;
    18.                         sub[j] = new PlayerLoopSystem();
    19.                         continue;
    20.                     }
    21.                     if (sub[j].type == typeof(PresentationSystemGroup) && j == loopIndexes.PresentationIndex)
    22.                     {
    23.                         sub[j].updateDelegate = null;
    24.                         sub[j] = new PlayerLoopSystem();
    25.                         continue;
    26.                     }
    27.                     if (sub[j].type == typeof(InitializationSystemGroup) && j == loopIndexes.InitializationIndex)
    28.                     {
    29.                         sub[j].updateDelegate = null;
    30.                         sub[j] = new PlayerLoopSystem();
    31.                         continue;
    32.                     }
    33.  
    34.                     tempSub[index] = sub[j];
    35.                     index++;
    36.                 }
    37.                
    38.                 Array.Resize(ref tempSub, index);
    39.                 resultSub.subSystemList = tempSub;
    40.                    
    41.                 resultPls.subSystemList[i] = resultSub;
    42.             }
    43.  
    44.             ScriptBehaviourUpdateOrder.SetPlayerLoop(resultPls);
    45.         }
    46.        
    47.         public static PlayerLoopTuple AddWorldToPlayerLoop(this World world)
    48.         {
    49.             var result = PlayerLoopTuple.CreateEmpty;
    50.            
    51.             if (ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList == null)
    52.             {
    53.                 ScriptBehaviourUpdateOrder.UpdatePlayerLoop(world);
    54.                 for (var i = 0; i < ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList.Length; i++)
    55.                 {
    56.                     var sub = ScriptBehaviourUpdateOrder.CurrentPlayerLoop.subSystemList[i].subSystemList;
    57.                     for (var j = 0; j < sub?.Length; j++)
    58.                     {
    59.                         if (sub[j].type == typeof(SimulationSystemGroup))
    60.                         {
    61.                             result.SimulationIndex = j;
    62.                         }
    63.                         else if (sub[j].type == typeof(PresentationSystemGroup))
    64.                         {
    65.                             result.PresentationIndex = j;
    66.                         }
    67.                         else if (sub[j].type == typeof(InitializationSystemGroup))
    68.                         {
    69.                             result.InitializationIndex = j;
    70.                         }
    71.                     }
    72.                 }
    73.                 return result;
    74.             }
    75.  
    76.             // Take the previous systems that were running.
    77.             var a = ScriptBehaviourUpdateOrder.CurrentPlayerLoop;
    78.  
    79.             // Create a player loop from the given world.
    80.             ScriptBehaviourUpdateOrder.UpdatePlayerLoop(world);
    81.             var b = ScriptBehaviourUpdateOrder.CurrentPlayerLoop;
    82.  
    83.             var resultPls = new PlayerLoopSystem {subSystemList = new PlayerLoopSystem[a.subSystemList.Length]};
    84.            
    85.            
    86.             for (var i = 0; i < a.subSystemList.Length; i++)
    87.             {
    88.                 var aSub = a.subSystemList[i].subSystemList;
    89.                 var bSub = b.subSystemList[i].subSystemList;
    90.  
    91.                 var resultSub = a.subSystemList[i];
    92.                 resultSub.subSystemList = new PlayerLoopSystem[aSub.Length + 1];
    93.  
    94.                 for (var j = 0; j < aSub.Length; j++)
    95.                 {
    96.                     resultSub.subSystemList[j] = aSub[j];
    97.                 }
    98.  
    99.                 for (var j = 0; j < bSub?.Length; j++)
    100.                 {
    101.                     // Only add the systems that are specific to the world.
    102.                     // Don't add other systems, they are internal to Unity (e.g. like WaitForTargetFPS).
    103.  
    104.                     if (bSub[j].type == typeof(SimulationSystemGroup))
    105.                     {
    106.                         result.SimulationIndex = aSub.Length;
    107.                         resultSub.subSystemList[aSub.Length] = bSub[j];
    108.                     }
    109.                     else if (bSub[j].type == typeof(PresentationSystemGroup))
    110.                     {
    111.                         result.PresentationIndex = aSub.Length;
    112.                         resultSub.subSystemList[aSub.Length] = bSub[j];
    113.                     }
    114.                     else if (bSub[j].type == typeof(InitializationSystemGroup))
    115.                     {
    116.                         result.InitializationIndex = aSub.Length;
    117.                         resultSub.subSystemList[aSub.Length] = bSub[j];
    118.                     }
    119.                 }
    120.  
    121.                 resultPls.subSystemList[i] = resultSub;
    122.             }
    123.  
    124.             ScriptBehaviourUpdateOrder.SetPlayerLoop(resultPls);
    125.             return result;
    126.         }
     
    Dr_SuiuS, tarahugger and psuong like this.