Search Unity

  1. Want to see 2020.1b in action? Sign up for our Beta 2020.1 Overview Webinar on April 20th for a live presentation from our evangelists and a Q&A session with guests from R&D.
    Dismiss Notice
  2. Interested in giving us feedback? Join our online research interviews on a broad range of topics and share your insights with us.
    Dismiss Notice
  3. We're hosting a webinar for the new Input System where you'll be able to get in touch with the devs. Sign up now and share your questions with us in preparation for the session on April 15.
    Dismiss Notice
  4. Dismiss Notice

[SOLVED] How to Destroy World correctly?

Discussion in 'Data Oriented Technology Stack' started by AGeorgy, Mar 28, 2019.

  1. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    37
    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.
     
    EvansT likes this.
  2. Srokaaa

    Srokaaa

    Joined:
    Sep 18, 2018
    Posts:
    99
    This title wins a reward for best phrased question :p
     
    Flurgle, mkracik, Athomield3D and 8 others like this.
  3. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    37
    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:
    37
    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:
    578
    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:
    37
    It depends
     
  10. AGeorgy

    AGeorgy

    Joined:
    Sep 16, 2013
    Posts:
    37
    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.         }
     
    tarahugger and psuong like this.
unityunity