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. Dismiss Notice

Question Question about EntityManager.Instantiate

Discussion in 'Entity Component System' started by Bagazi, Sep 3, 2023.

  1. Bagazi

    Bagazi

    Joined:
    Apr 18, 2018
    Posts:
    609
    If an authoring class has an object attached to it that is a prefab (an asset), and you want to load this prefab object and convert it into an entity in the world, can you do it directly in the Baker function using getEntity, or do you eventually need to use EntityManager to instantiate an entity?

    For example, in the project you mentioned (CharacterControllerSamples), there is a practice related to CameraPrefabEntity:



    Code (CSharp):
    1.     public void OnUpdate(ref SystemState state)
    2.     {
    3.         // Game init
    4.         if (SystemAPI.HasSingleton<SceneInitialization>())
    5.         {
    6.             ref SceneInitialization sceneInitializer = ref SystemAPI.GetSingletonRW<SceneInitialization>().ValueRW;
    7.            
    8.             // Cursor
    9.             Cursor.lockState = CursorLockMode.Locked;
    10.             Cursor.visible = false;
    11.  
    12.             // Spawn player
    13.             Entity playerEntity = state.EntityManager.Instantiate(sceneInitializer.PlayerPrefabEntity);
    14.  
    15.             // Spawn character at spawn point
    16.             Entity characterEntity = state.EntityManager.Instantiate(sceneInitializer.CharacterPrefabEntity);
    17.             LocalTransform spawnTransform = SystemAPI.GetComponent<LocalTransform>(sceneInitializer.CharacterSpawnPointEntity);
    18.             SystemAPI.SetComponent(characterEntity, LocalTransform.FromPositionRotation(spawnTransform.Position, spawnTransform.Rotation));
    19.  
    20.             // Spawn camera
    21.             Entity cameraEntity = state.EntityManager.Instantiate(sceneInitializer.CameraPrefabEntity);
    22.             state.EntityManager.AddComponentData(cameraEntity, new MainEntityCamera());
    23.  
    24.             // Assign camera & character to player
    25.             PlatformerPlayer player = SystemAPI.GetComponent<PlatformerPlayer>(playerEntity);
    26.             player.ControlledCharacter = characterEntity;
    27.             player.ControlledCamera = cameraEntity;
    28.             SystemAPI.SetComponent(playerEntity, player);
    29.            
    30.             state.EntityManager.DestroyEntity(SystemAPI.GetSingletonEntity<SceneInitialization>());
    31.         }
    32.     }

    https://github.com/Unity-Technologi...ets/Scripts/Misc/SceneInitializationSystem.cs




    Entity cameraEntity = state.EntityManager.Instantiate(sceneInitializer.CameraPrefabEntity);

    Is the purpose of this function to create a copy of an entity? Why is it necessary to copy the entity instead of directly using it when the entity has already been declared elsewhere? I want to understand the reasons and underlying principles behind this approach. It reminds me of the way that used to initialize a prefab in OOP by first loading the prefab and then instantiating it. I'm wondering if there are similarities, but this is purely my personal speculation.
     
  2. StickyKevin

    StickyKevin

    Joined:
    Jul 1, 2020
    Posts:
    22
    In your use case the Entity that should be instantiated is a "PrefabEntity", it is a Prefab converted to an Entity.
    This Entity has a PrefabEntity ComponentData tag which excludes it from runtime systems. During instantiating, the Entity is indeed duplicated, but loses its PrefabEntity component.
    This way the new Entity will be included in runtime systems.

    Every GameObject or Prefab that is a reference value in an authoring component in a subscene, will be converted to a PrefabEntity.
    These PrefabEntities are not visible nor included in runtime systems (as mentioned before).
    You can see them as a sort of custom template Entities that are ready to be used by instantiating them.
    See this for more info on the workflow: https://docs.unity3d.com/Packages/com.unity.entities@1.0/manual/ecs-workflows.html
     
    Last edited: Sep 7, 2023
    Bagazi likes this.
  3. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Incorrect a bit. Only referenced prefabs will have
    Prefab : IComponentData
    , if you reference another GO in subscene - it wouldn't have
    Prefab
    component on it.
    Simple proof:
    upload_2023-9-7_11-4-20.png
    upload_2023-9-7_11-5-41.png
    upload_2023-9-7_11-4-55.png
    upload_2023-9-7_11-5-21.png
     
  4. StickyKevin

    StickyKevin

    Joined:
    Jul 1, 2020
    Posts:
    22