Search Unity

Question [0.51] IDeclareReferencedPrefabs & GetPrimaryEntity broken reference when subscene closed

Discussion in 'NetCode for ECS' started by staringatlights, Oct 27, 2022.

  1. staringatlights

    staringatlights

    Joined:
    Sep 1, 2013
    Posts:
    29
    I using NetCode 0.51 and the subscene workflow. I have a GameObject in the subscene using
    IConvertGameObjectToEntity and IDeclareReferencedPrefabs to manage a list of unit prefabs in the inspector and have them translate to entities in ECS. When the subscene is open for editing, everything works fine, however when the subscene is closed (or this scene is loaded from another scene), the prefab entity association seems to be broken.

    Code (CSharp):
    1.  
    2. [Serializable]
    3. public struct UnitDefinitionAuthoring
    4. {
    5.     public GameObject prefab;
    6.     public GameObject buildingPrefab;
    7. }
    8.  
    9. public struct UnitDefinition
    10. {
    11.     public Entity prefab;
    12.     public Entity buildingPrefab;
    13. }
    14.  
    15. public class UnitDefinitions : IComponentData
    16. {
    17.     public UnitDefinition[] Value;
    18. }
    19.  
    20.     public class UnitPrefabManager : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
    21.     {
    22.         public UnitDefinitionAuthoring[] definitions;
    23.  
    24.         public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    25.         {
    26.             UnitDefinition[] defs = new UnitDefinition[definitions.Length];
    27.  
    28.             for (var i = 0; i < definitions.Length; i++)
    29.             {
    30.                 var definition = definitions[i];
    31.  
    32.                 defs[i] = new UnitDefinition()
    33.                 {
    34.                     prefab = conversionSystem.GetPrimaryEntity(definition.prefab),
    35.                     buildingPrefab = conversionSystem.GetPrimaryEntity(definition.buildingPrefab)
    36.                 };
    37.             }
    38.  
    39.             var componentDefinitions = new UnitDefinitions()
    40.             {
    41.                 Value = defs
    42.             };
    43.  
    44.             dstManager.AddComponentObject(entity, componentDefinitions);
    45.             dstManager.AddComponent<UnitPrefabManager>(entity);
    46.         }
    47.  
    48.         public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
    49.         {
    50.             foreach (var def in definitions)
    51.             {
    52.                 GeneratedAuthoringComponentImplementation.AddReferencedPrefab(referencedPrefabs, def.prefab);
    53.                 GeneratedAuthoringComponentImplementation.AddReferencedPrefab(referencedPrefabs, def.buildingPrefab);
    54.  
    55.             }
    56.         }
    57.     }
    58.  
    The idea is to have a list of possible units editable in the editor inspector, but translate to ECS.

    In a system running in ClientSimulationSystemGroup, I'm trying to access those prefab entities:

    Code (CSharp):
    1.         var entity = GetSingletonEntity<UnitDefinitions>();
    2.         _definitions = EntityManager.GetComponentObject<UnitDefinitions>(entity);
    3.      
    4.         // add a button to the UI for each buildable unit
    5.         foreach (var definition in _definitions.Value)
    6.         {
    7.             Debug.Log($"unit definition: {definition.prefab}");
    8.             var buildUnit = _settings.buildUnitTemplate.CloneTree();
    9.             var button = buildUnit.Q<BuildButtonCVE>();
    10.             var unit = EntityManager.GetComponentData<Unit>(definition.prefab);
    11.             button.buildingPrefabName = unit.unitStats.Value.unitName.ToString();
    12.             _buildMenu.Add(buildUnit);
    13.         }
    The call to EntityManager.GetComponentData<Unit>(definition.prefab); causes the error:

    ArgumentException: The entity does not exist.
    Unity.Entities.EntityComponentStore.AssertEntityHasComponent (Unity.Entities.Entity entity, Unity.Entities.ComponentType componentType) (at Library/PackageCache/com.unity.entities@0.51.1-preview.21/Unity.Entities/EntityComponentStoreDebug.cs:298)
    Unity.Entities.EntityComponentStore.AssertEntityHasComponent (Unity.Entities.Entity entity, System.Int32 componentType) (at Library/PackageCache/com.unity.entities@0.51.1-preview.21/Unity.Entities/EntityComponentStoreDebug.cs:320)
    Unity.Entities.EntityDataAccess.GetComponentData[T] (Unity.Entities.Entity entity) (at Library/PackageCache/com.unity.entities@0.51.1-preview.21/Unity.Entities/EntityDataAccess.cs:1063)
    Unity.Entities.EntityManager.GetComponentData[T] (Unity.Entities.Entity entity) (at Library/PackageCache/com.unity.entities@0.51.1-preview.21/Unity.Entities/EntityManager.cs:325)


    My debug line shows that when the subscene is closed, the entity reference is incorrect. For example it will be looking for "Entity(5:0)" when the real prefab entity for that unit is "Entity(21:0)".

    Can anyone shed some light on this?