Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Restart ecs simulation?

Discussion in 'Entity Component System' started by Bas-Smit, Sep 24, 2019.

  1. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    272
    Is there an easy way to complete restart an ecs simulation? I tried variations on the following without success...

    World.Active.EntityManager.DestroyEntity(World.Active.EntityManager.GetAllEntities());
    World.Active.Dispose();
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex, LoadSceneMode.Single);


    Thanks, Bas
     
    shotoutgames and NotaNaN like this.
  2. swejk

    swejk

    Joined:
    Dec 22, 2013
    Posts:
    20
    I am using DefaultWorldInitialization to do this for me. You still need to dispose old world and scenes.
    Code (CSharp):
    1.    
    2. World.Active.Dispose();
    3. SceneManager.LoadScene("Intro", LoadSceneMode.Single);
    4. DefaultWorldInitialization.Initialize("Default World", false);
    5.  
     
    NotaNaN likes this.
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    I recently blueprinted a full scene management framework so I won't be using this code much longer. I don't keep state in systems, so I don't actually dispose the world and create a new one.
    Code (CSharp):
    1. using Unity.Entities;
    2. using UnityEngine.SceneManagement;
    3.  
    4. namespace Latios
    5. {
    6.     internal struct LatiosSceneChangeDummyTag : IComponentData { }
    7.  
    8.     [AlwaysUpdateSystem]
    9.     internal class DestroyEntitiesSceneChangeSystem : SubSystem
    10.     {
    11.         private EntityQuery destroyQuery = null;
    12.  
    13.         protected override void OnCreate()
    14.         {
    15.             EntityQueryDesc desc = new EntityQueryDesc
    16.             {
    17.                 All = new ComponentType[]
    18.                 {
    19.                     typeof(LatiosSceneChangeDummyTag)
    20.                 },
    21.                 None = new ComponentType[]
    22.                 {
    23.                     typeof(SingletonTag),
    24.                     typeof(DontDestroyOnSceneChangeTag)
    25.                 }
    26.             };
    27.             destroyQuery                = GetEntityQuery(desc);
    28.             SceneManager.sceneUnloaded += RealUpdateOnSceneChange;
    29.         }
    30.  
    31.         protected override void OnUpdate()
    32.         {}
    33.  
    34.         private void RealUpdateOnSceneChange(Scene unloaded)
    35.         {
    36.             if (unloaded.isSubScene)
    37.                 return;
    38.  
    39.             //Why are add and remove inconsistent?
    40.             EntityManager.AddComponent(EntityManager.UniversalQuery, typeof(LatiosSceneChangeDummyTag));
    41.             EntityManager.DestroyEntity(destroyQuery);
    42.             EntityManager.RemoveComponent<LatiosSceneChangeDummyTag>(EntityManager.UniversalQuery);
    43.         }
    44.     }
    45. }
     
    NotaNaN and Bas-Smit like this.
  4. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    272

    Thanks, this works for me, I just use
    World.DisposeAllWorlds();
    to get rid of our streaming worlds
     
  5. jdtec

    jdtec

    Joined:
    Oct 25, 2017
    Posts:
    299
    I'm trying to destroy all my worlds without the restart.

    Just calling
    World.DisposeAllWorlds();
    gives me this error (and a similar one for PresentationSystemGroup):

    Does anyone know how to unregister the system groups from the ScriptBehaviourUpdateOrder or a better way to achieve the goal of destroying the worlds? I don't want to change scene, I just want to destroy the worlds and that's it.

    Code (CSharp):
    1. InvalidOperationException: Unity.Entities.SimulationSystemGroup has already been destroyed. It may not be used anymore.
    2. Unity.Entities.ComponentSystemBase.CheckExists () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:323)
    3. Unity.Entities.ComponentSystemBase.ShouldRunSystem () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:339)
    4. Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:783)
    5. Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
    6. Unity.Entities.ScriptBehaviourUpdateOrder+DummyDelegateWrapper.TriggerUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ScriptBehaviourUpdateOrder.cs:144)
     
  6. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    272
    By destroying your world you mean destroy all entities?

    EntityManager.DestroyEntity(EntityManager.GetAllEntities());


    removing systems:

    ComponentSystemGroup.RemoveSystemFromUpdateList(ComponentSystemBase sys)


    Find your system to remove:

    World.GetExistingSystem(typeof(system))
     
  7. jdtec

    jdtec

    Joined:
    Oct 25, 2017
    Posts:
    299
    Yes, but also all systems and whatever other world data there might be.

    I found a way to make it work. I call:

    World.DisposeAllWorlds ();
    DefaultWorldInitialization.Initialize ("Default World", false);


    As has been suggested, however, I also needed to call it from a coroutine that waits until the end of the frame.