Search Unity

ComponentData wrapped by ComponentDataWrapper is not updated

Discussion in 'Entity Component System' started by yatagarasu, Jun 23, 2018.

  1. yatagarasu

    yatagarasu

    Joined:
    Apr 24, 2013
    Posts:
    28
    I have a simple GameObject with a Behaviour which read data from ComponentData.
    It is not updated until I select object in hierarchy view.
    Is it a bug or something wrong with my code?

    Code (CSharp):
    1. public struct EntityData : IComponentData
    2. {
    3.     public float Scale;
    4. }
    5.  
    6. public class EntityDataComponent : ComponentDataWrapper<EntityData>
    7. {
    8. }
    9.  
    10. public class Behaviour : MonoBehaviour {
    11.  
    12.     // Update is called once per frame
    13.     void Update () {
    14.         var data = GetComponent<EntityDataComponent>();
    15.  
    16.         // here data.Value.Scale is zero until I select object in Hierarchy view.
    17.         transform.localScale = new float3(data.Value.Scale);
    18.     }
    19. }
    20.  
    21. namespace Assets
    22. {
    23.     public class Bootstrap : MonoBehaviour
    24.     {
    25.         [SerializeField]
    26.         GameObject m_Prefab;
    27.  
    28.         protected void Start()
    29.         {
    30.             // Here GameObject is created and it's entity data is set.
    31.             var em = World.Active.GetOrCreateManager<EntityManager>();
    32.  
    33.             var entity = Instantiate(m_Prefab).GetComponent<GameObjectEntity>().Entity;
    34.             em.SetComponentData(entity, new EntityData { Scale = 3.0f });
    35.         }
    36.     }
    37. }
    38.  
     
  2. yatagarasu

    yatagarasu

    Joined:
    Apr 24, 2013
    Posts:
    28
  3. yatagarasu

    yatagarasu

    Joined:
    Apr 24, 2013
    Posts:
    28
    Really nobody know how to fix that problem?
     
  4. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    In your Update()

    Code (CSharp):
    1. void Update () {
    2.     // You need this
    3.     var em = World.Active.GetOrCreateManager<EntityManager>();
    4.     Entity entity = GetComponent<GameObjectEntity>().Entity;
    5.     var data = em.GetComponentData<EntityData>(entity);
    6.  
    7.     // instead of this
    8.     // var data = GetComponent<EntityDataComponent>();
    9. }
    The ComponentDataWrapper EntityDataComponent is only there to bootstrap the IComponentData EntityData to the EntityManager when it's first initialised. After that it's of no use AFAIK.
    You need to retrieve the EntityData component from the Entity as opposed to the EntityDataComponent wrapper from the GameObject.
     
    yatagarasu likes this.
  5. yatagarasu

    yatagarasu

    Joined:
    Apr 24, 2013
    Posts:
    28
    Thanks, that works.
    Is that intended behavior? And I should get data like this, or it will be changed some day?
     
  6. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    @yatagarasu My suggestion would be to rather have a system that takes care of keeping this synchronised properly. Using a hybrid systems approach for this is likely the best approach depending on the GameObject components you're trying to keep in sync. I know that there's already a job type that allows for a TransformAccessArray to be processed in parallel which should provide you with the functionality you need from an ECS perspective instead of trying to manage it from a MonoBehaviour perspective.
     
  7. yatagarasu

    yatagarasu

    Joined:
    Apr 24, 2013
    Posts:
    28
    Cyberwiz15, you mean i need to copy EntityData to EntityDataComponent in some system?
    I thought it should be done automatically.
     
  8. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    @yatagarasu let me first understand the behaviour that's wrong. I suspect the GameObject's transform scale isn't set correctly until selected in the hierarchy view? While @jooleanlogic 's solution is a working solution, I'm trying to fully understand what it is you're trying to achieve as well as provide you with a solution to your problem that better fits the ECS paradigm.
     
  9. yatagarasu

    yatagarasu

    Joined:
    Apr 24, 2013
    Posts:
    28
    The real problem is that GameObject's ComponentData is not updated until it is selected in hierarchy view (and i am not sure if it is update after, but at least one time it is updated).
    What I am trying to achieve - is to update data in Hybryd ECS part from Pure ECS part - @jooleanlogic 's soultion works just fine. Still it looks a little bit strange that I can not get entity's data from ComponentDataWrapper
     
  10. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    The problem is trying to access the entity's data from outside the ECS framework to a container that was built to precise the framework with a way of accessing data. Your example is setting three transform component's scale value. It is completely possible to set this from a system though instead of trying to do this from a MonoBehaviour. Unity provides the TransformAccess component that can be injected to a system via the TransformAccessArray. I'll try to post an example once I can get in front of my computer again in a day or so, but you should be able to find some info about these things on the forum or the documentation on GutHub.
     
  11. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    Try to put [Serializable] attribute on your EntityData struct.