#Assigning Entities to Subscenes.

1 messages · Page 1 of 1 (latest)

acoustic vortex
#

I really cannot figure out how to move or even instantiate entities across subscenes, I tried reassigning the shared components entity to the subscene I wanted but this seems to break everything

 {
    foreach(var entity in _applySceneTagEntities)
     {
       state.EntityManager.SetSharedComponent(entity, new SceneTag
         {
          SceneEntity = SystemAPI.GetSingleton<MapLoadState>().CurrentSceneEntity
         }); 
     }
     _applySceneTagEntities.Clear();
 }````
This seems to break a lot of things including putting my editor in a error loop that can only be fixed by restarting unity. >< .
The problem is,I have maps for my game I'm using subscenes to manage the maps. When the user builds a structure on the map and then we want to unload that map, those user built entities are assigned to the subscene where the authoring component was, which is in my bootstrap subscene.  I want to be able to instantiate a entity and set its subscene reference so they get unloaded when the map unloads.
echo sphinx
#

This code works

[ContextMenu("Test")]
public void Test()
{
    var world = World.DefaultGameObjectInjectionWorld;
    var manager = world.EntityManager;

    // main menu scene
    var sceneHash = new Hash128(4090383369, 1295123372, 2242234277, 471185253);
    var sceneEntity = SceneSystem.GetSceneEntity(world.Unmanaged, sceneHash);

    var ecb = new EntityCommandBuffer(Allocator.Temp);
    
    var testEntity = ecb.CreateEntity();
    ecb.AddSharedComponent(testEntity, new SceneTag { SceneEntity = sceneEntity });
    ecb.SetName(testEntity, "Scene Test Entity");

    ecb.Playback(manager);
}```
echo sphinx
tight topaz
echo sphinx
tight topaz
#

ECB is useful in places where you are not allowed to make structural changes. For example: in the middle of a job chain.

#

In such case, structural changes must be deferred to the next frame. But your code above isn't about that case. This call ecb.Playback(manager); will make a structural change anyway, right at that place and that frame. So it's just the same as calling EntityManager methods in that function.

#

In such case, structural changes must be deferred to the next frame.
Or to be more precise, structural changes must be deferred to the place where it's fine for them to happen. This is where ECB systems come into the play. ECB systems specify the points in time where it's safe to make structural changes. At those points, they will playback the list of recorded commands using EntityManager.

#

For example, ECB.CreateEntity() just records a command so that EM.CreateEntity() can be invoked later in time.

#

It would be more appropriate if your code look like this instead

{
    var world = World.DefaultGameObjectInjectionWorld;

    // main menu scene
    var sceneHash = new Hash128(4090383369, 1295123372, 2242234277, 471185253);
    var sceneEntity = SceneSystem.GetSceneEntity(world.Unmanaged, sceneHash);

    var ecb = ... // retrieved from an ECB system
    
    var testEntity = ecb.CreateEntity();
    ecb.AddSharedComponent(testEntity, new SceneTag { SceneEntity = sceneEntity });
    ecb.SetName(testEntity, "Scene Test Entity");

    // The aforementioned ECB system will play it back later
}
tight topaz
acoustic vortex
#

hmm thanks for the feedback i feel this may be something to do with my use of prefabs @echo sphinx @tight topaz

      {
            var bluePrefab = Entity.Null;
            
            switch (blueprintData.Category)
            {
                case BuildCategory.Turret:
                    var turretPrefabs =
                        SystemAPI.GetBuffer<BlueprintTurretPrefabEntityBuffer>(_prefabsEntity);
                    bluePrefab = turretPrefabs[blueprintData.BuildType].Prefab;
                    break;
                case BuildCategory.Wall:
                    var wallPrefabs =
                        SystemAPI.GetBuffer<BlueprintWallPrefabEntityBuffer>(_prefabsEntity);
                    bluePrefab = wallPrefabs[blueprintData.BuildType].Prefab;
                    break;
                case BuildCategory.Collector:
                    break; 
            }
            
            if (bluePrefab == Entity.Null) return;
            
            if (!SystemAPI.TryGetSingleton<MapLoadState>(out var mapLoadState)) return;
            
            var world = World.DefaultGameObjectInjectionWorld;
            
            var sceneHash = mapLoadState.CurrentMapHashCode;
            var sceneEntity = SceneSystem.GetSceneEntity(world.Unmanaged, sceneHash);
            
            var ecb =
                SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
                    .CreateCommandBuffer(state.WorldUnmanaged);
            
            var blueprintEnt = ecb.Instantiate(bluePrefab);
            
            ecb.SetSharedComponent(blueprintEnt, new SceneTag { SceneEntity = sceneEntity });

        }```
#

Set or add shared component results in the same error, in the editor
ArgumentException: Key: SubSceneTag: Entity(127:1) is not present in the NativeParallelHashMap.

Constructors and field initializers will be executed from the loading thread when loading a scene.```
My other code works fine its just when we add ```ecb.SetSharedComponent(blueprintEnt, new SceneTag { SceneEntity = sceneEntity }); or 
ecb.AddComponent(blueprintEnt, new SceneTag { SceneEntity = sceneEntity });
``` we get those errors.
acoustic vortex
#

I checked my scene hash is correct for the current scene i want to assign the entities to.

#

And it pulls the correct entity that is the subscene

acoustic vortex
#

even going this way, with the SceneSystem.GetSceneEntity call it was still getting the same entity i assined to my component MapLoadState in another system, The fact of the matter is i cannot set the shared component. no matter how i grab the scene entity.

acoustic vortex
#

Wait this is an editor issue? The editor is erroring out because im swapping objects between subscenes and the scene does not have the item anymore so we get ArgumentException: Key: SubSceneTag: Entity(127:1) is not present in the NativeParallelHashMap. ??? what on earth

#

I build the project with debugging and did not get this error.