Search Unity

Load a subscene to a specific world

Discussion in 'Entity Component System' started by sebas77, Sep 26, 2019.

  1. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,643
    Hello,

    How can I load a subscene into a world that is not the default one?
     
    Neiist and e199 like this.
  2. paul-figiel

    paul-figiel

    Joined:
    Feb 9, 2017
    Posts:
    9
  3. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,643
    Thanks, the convert does the conversion at run time doesn't it? I want to serialize back the converted world instead, not converting it at run time. Please let me know if I am wrong.
     
  4. paul-figiel

    paul-figiel

    Joined:
    Feb 9, 2017
    Posts:
    9
    You can convert a serialized scene at runtime using the function above.
    Also, World != Scene, you serialize your DOTS scene by creating a subscene, you can then load it into the desired world at runtime.

    Serialized DOTS subscenes are serialized in a runtime friendly way using all the conversion systems, and this is done when you rebuild the entity cache of the subscene so not in runtime.

    I don't know if this answers your question ?
     
  5. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,643
    I think so, I have to check where the Scene class is declared. Intuitively I think you are telling me that I can load a subscene as addressable asset in to a Scene object and use it in the ConvertScene function.

    Edit: it appears that Scene is from the SceneManager class, will experiment
     
    Last edited: Sep 27, 2019
  6. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,643
    did I quick test with this:

    Code (CSharp):
    1.  
    2. var scene = SceneManager.LoadScene(ECS_PLANE, new LoadSceneParameters(LoadSceneMode.Additive));
    3. GameObjectConversionUtility.ConvertScene
    4.     (scene, new GameObjectConversionSettings(rollbackWorld, GameObjectConversionUtility.ConversionFlags.AddEntityGUID));
    5.  
    didn't work, but to be fair, I have no clue what the conversionflags are about
     
  7. scobi

    scobi

    Unity Technologies

    Joined:
    May 14, 2014
    Posts:
    32
    @sebas77 what are you wanting to achieve by loading into a separate world? Would you tell us about your project?
     
  8. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,643
  9. Fabrice_Lete

    Fabrice_Lete

    Unity Technologies

    Joined:
    May 5, 2018
    Posts:
    55
    So right now this can be achieved but it could definitely be simpler. The idea is that when SubScene MB are enabled they'll register into every ECS world with a SceneSystem present at the time. Once that is done, it's a matter of adding the RequestSceneLoaded tag to the SubScene and SubScene sections we're interested in.

    Now in practice, it would look something like this:

    Code (CSharp):
    1. public class MyCustomBootstrap : ICustomBootstrap
    2. {
    3.     public bool Initialize(string defaultWorldName)
    4.     {
    5.         World.DefaultGameObjectInjectionWorld = new World(defaultWorldName);
    6.         var anotherWorld = new World("AnotherWorld");
    7.  
    8.         var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
    9.  
    10.         DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(World.DefaultGameObjectInjectionWorld, systems);
    11.         ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.DefaultGameObjectInjectionWorld);
    12.  
    13.         systems.Add(typeof(TriggerSubSceneLoad));
    14.  
    15.         DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(anotherWorld, systems);
    16.         ScriptBehaviourUpdateOrder.UpdatePlayerLoop(anotherWorld, ScriptBehaviourUpdateOrder.CurrentPlayerLoop);
    17.  
    18.         return true;
    19.     }
    20. }
    21.  
    22. [DisableAutoCreation]
    23. public class TriggerSubSceneLoad : ComponentSystem
    24. {
    25.     Entity m_SceneEntity;
    26.  
    27.     protected override void OnUpdate()
    28.     {
    29.         if (m_SceneEntity == Entity.Null)
    30.         {
    31.             var sceneSystem = World.GetExistingSystem<SceneSystem>();
    32.             var sceneHash = new Hash128("c4e67b524908a5446bf4e40bb4213bf9");
    33.             m_SceneEntity = sceneSystem.GetSceneEntity(sceneHash);
    34.             if (m_SceneEntity != Entity.Null)
    35.             {
    36.                 EntityManager.AddComponent<RequestSceneLoaded>(m_SceneEntity);
    37.  
    38.                 Entities.ForEach((Entity sceneSectionEntity, ref SceneSectionData sceneSectionData) =>
    39.                 {
    40.                     if (sceneSectionData.SceneGUID == sceneHash)
    41.                         EntityManager.AddComponent<RequestSceneLoaded>(sceneSectionEntity);
    42.                 });
    43.             }
    44.         }
    45.     }
    46. }
     
  10. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    Does this code actually work in the new Entities package? And not break when conversion worlds are created? If so, that is hype!
     
  11. saarg

    saarg

    Joined:
    Mar 9, 2017
    Posts:
    31
    Correct me if I'm wrong but what you said doesn't seem to be right for entities 0.1.1, I'm guessing it will be true for entities 0.2.