Search Unity

Shared component data conversion broken?

Discussion in 'Entity Component System' started by any_user, Mar 18, 2020.

  1. any_user

    any_user

    Joined:
    Oct 19, 2008
    Posts:
    374
    I'm trying to convert shared components, but I'm encountering some issues. Aside of the missing implementation of GenerateAuthoringComponent, I also had problems converting the component manually with IConvertGameObjectToEntity.

    In this example, "someEntity" is found during conversion, but mapped to an unrelated entity after conversion. Any idea how to make this work?

    Code (CSharp):
    1. using Unity.Entities;
    2. using UnityEngine;
    3.  
    4. public class MyComponentAuthoring : MonoBehaviour, IConvertGameObjectToEntity
    5. {
    6.     public GameObject someObject;
    7.  
    8.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    9.     {
    10.         dstManager.AddSharedComponentData(entity,new MyComponent
    11.         {
    12.             someEntity = conversionSystem.GetPrimaryEntity(someObject)
    13.         });
    14.     }
    15. }
    16. public struct MyComponent : ISharedComponentData
    17. {
    18.     public Entity someEntity;
    19. }
    Update:

    Found a part of issue, it was not related to the conversion, but to iterating through all shared components. I assumed the list passed to GetAllUniqueSharedComponentData gets cleared (like when using MonoBehaviour.GetComponents()), but instead they get added to the existing list. So the shared components from previous frames are still there, which obviously isn't useful in this case.

    Another thing that doesn't help debugging:
    Code (CSharp):
    1.  
    2.  
    3. Debug.Log(comp.entity) // "Entity.Null"
    4. Debug.Log(EntityManager.GetName(comp.entity)); // "Scene (LiveLink): myScene" (???)
    5.  
    After fixing these issues, the initial problem still occurs. After converting, sharedValue.someEntity has a different value. Here's the full code:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using Unity.Entities;
    3. using UnityEngine;
    4.  
    5. public class MyComponentAuthoring : MonoBehaviour, IConvertGameObjectToEntity
    6. {
    7.     public GameObject sourceIndexMesh;
    8.  
    9.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    10.     {
    11.         var primaryEntity = conversionSystem.GetPrimaryEntity(sourceIndexMesh);
    12.         dstManager.AddSharedComponentData(entity,new MyComponent
    13.         {
    14.             someEntity = primaryEntity
    15.         });
    16.      
    17.         Debug.Log(dstManager.GetName( primaryEntity)); // "Some Entity"
    18.     }
    19. }
    20.  
    21. public struct MyComponent : ISharedComponentData
    22. {
    23.     public Entity someEntity;
    24. }
    25.  
    26. public class MySystem : SystemBase
    27. {
    28.     List<MyComponent> sharedValues;
    29.     protected override void OnCreate()
    30.     {
    31.         base.OnCreate();
    32.         sharedValues = new List<MyComponent>();
    33.     }
    34.     protected override void OnUpdate()
    35.     {
    36.         sharedValues.Clear(); // required
    37.         EntityManager.GetAllUniqueSharedComponentData(sharedValues);
    38.    
    39.         for (int sharedId = 1; sharedId < sharedValues.Count; sharedId++)
    40.         {
    41.             var sharedValue = sharedValues[sharedId];
    42.             Debug.Log( EntityManager.GetName( sharedValue.someEntity)); // "Unrelated Entity"
    43.         }
    44.     }
    45. }
     
    Last edited: Mar 18, 2020
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    sourceIndexMesh
    should be in List implemented by IDeclareReferencePrefab I guess