Hello,
How can I load a subscene into a world that is not the default one?
Hello,
How can I load a subscene into a world that is not the default one?
Hi,
Looks like GameObjectConversionUtility.ConvertScene does this.
https://docs.unity3d.com/Packages/com.unity.entities@0.0/api/Unity.Entities.GameObjectConversionUtility.html
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.
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 ?
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
did I quick test with this:
var scene = SceneManager.LoadScene(ECS_PLANE, new LoadSceneParameters(LoadSceneMode.Additive));
GameObjectConversionUtility.ConvertScene
(scene, new GameObjectConversionSettings(rollbackWorld, GameObjectConversionUtility.ConversionFlags.AddEntityGUID));
didn’t work, but to be fair, I have no clue what the conversionflags are about
@sebas771 what are you wanting to achieve by loading into a separate world? Would you tell us about your project?
Our defaultWorld is separated from our physic world. We have a scene with several static colliders that we are converting every launch, when they could be serialized in a ecs-friendly form. Our game is
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:
public class MyCustomBootstrap : ICustomBootstrap
{
public bool Initialize(string defaultWorldName)
{
World.DefaultGameObjectInjectionWorld = new World(defaultWorldName);
var anotherWorld = new World("AnotherWorld");
var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(World.DefaultGameObjectInjectionWorld, systems);
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.DefaultGameObjectInjectionWorld);
systems.Add(typeof(TriggerSubSceneLoad));
DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(anotherWorld, systems);
ScriptBehaviourUpdateOrder.UpdatePlayerLoop(anotherWorld, ScriptBehaviourUpdateOrder.CurrentPlayerLoop);
return true;
}
}
[DisableAutoCreation]
public class TriggerSubSceneLoad : ComponentSystem
{
Entity m_SceneEntity;
protected override void OnUpdate()
{
if (m_SceneEntity == Entity.Null)
{
var sceneSystem = World.GetExistingSystem<SceneSystem>();
var sceneHash = new Hash128("c4e67b524908a5446bf4e40bb4213bf9");
m_SceneEntity = sceneSystem.GetSceneEntity(sceneHash);
if (m_SceneEntity != Entity.Null)
{
EntityManager.AddComponent<RequestSceneLoaded>(m_SceneEntity);
Entities.ForEach((Entity sceneSectionEntity, ref SceneSectionData sceneSectionData) =>
{
if (sceneSectionData.SceneGUID == sceneHash)
EntityManager.AddComponent<RequestSceneLoaded>(sceneSectionEntity);
});
}
}
}
}
Does this code actually work in the new Entities package? And not break when conversion worlds are created? If so, that is hype!
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.