Search Unity

GetPrimaryEntity in a GameObjectConversionSystem return non-existant entity

Discussion in 'Entity Component System' started by alexandre-fiset, Nov 11, 2019.

  1. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    715
    I've been using GameObjectConversionSystem to convert gameobjects to entities, and I've encountered a weird issue.

    I used to use the GetPrimaryEntity method on my authoring component (which has a ConvertToEntity script on its game object), but for some reasons it won't work in a system that I created this morning.

    This:

    Code (CSharp):
    1. using Ui.Components;
    2. using Ui.Components.States;
    3. using Ui.Screens.Authoring;
    4. using Unity.Entities;
    5.  
    6. namespace Ui.Screens.Systems
    7. {
    8.     [UpdateInGroup(typeof(GameObjectConversionGroup))]
    9.     public class DpadInventoryConversionSystem : GameObjectConversionSystem
    10.     {
    11.         protected override void OnUpdate()
    12.         {
    13.             Entities.ForEach((DpadInventoryAuthoring authoring) =>
    14.             {
    15.                 var entity = GetPrimaryEntity(authoring);
    16.                 EntityManager.AddComponentData(entity, new Hidden());
    17.  
    18.                 var dInventory = new DpadInventory
    19.                 {
    20.                     SelectedSlotColor = authoring.SelectedSlotColor,
    21.                     UnselectedColor = authoring.UnselectedColor,
    22.                     Slots = authoring.Slots,
    23.                     TopText = authoring.TopText,
    24.                     MiddleText = authoring.MiddleText,
    25.                     BottomText = authoring.BottomText
    26.                 };
    27.            
    28.                 EntityManager.AddSharedComponentData(entity, dInventory);
    29.            
    30.                 #if UNITY_EDITOR
    31.                 EntityManager.SetName(entity, "Ui.DpadInventory");
    32.                 #endif
    33.             });
    34.  
    35.         }
    36.  
    37.     }
    38. }
    Returns "ArgumentException: The entity does not exist" on the first AddComponentData line.

    Any idea why is that?
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    You're using wrong world.

    You need to use dstEntityManager
     
    NotaNaN, felipin and alexandre-fiset like this.
  3. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    715
    That is a bit confusing, but it works :p Thanks!
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    You have to understand how conversion works.

    The first step is to create entities for all go and attach all monobehaviour to them in a new temp conversion world.

    Then it creates new empty entities in the destination world for these entities.

    The conversion world is what you are iterating with entities.Foreach but when you call get primary entity you are getting the entity from the destination world so that you can add components to it.
     
    rafal_b, andywatts, davtam and 3 others like this.
  5. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Is there another transfer form dstWord to default world or is the dtsWorld the default world
     
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    dstWorld is whatever world you pass to the GameObjectConversionSettings when you create a conversion world. For default conversion, like scene conversion, this is going to be World.Active.
    So no, there is copy.
     
    Last edited: Nov 11, 2019
  7. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Thanks for the clarification, one more question, does CreateAdditionalEntity add the entity to the dstWorld
     
    davtam likes this.
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    Yes it's created on the destination world.

    This is something you can find out yourself looking at source code for 30 seconds.

    Code (CSharp):
    1. public Entity CreateAdditionalEntity(GameObject go)
    2.     {
    3.         #if DETAIL_MARKERS
    4.         using (m_CreateAdditional.Auto())
    5.         #endif
    6.         {
    7.             if (go == null)
    8.                 throw new ArgumentException("CreateAdditionalEntity must be called with a valid GameObject");
    9.  
    10.             var instanceID = go.GetInstanceID();
    11.             int index;
    12.             if (m_GameObjectToEntity.TryGetValue(instanceID, out index))
    13.             {
    14.                 int count = m_Entities.CountLinkedList(index);
    15.                 var entity = CreateEntity(go, count);
    CreateAdditionalEntity calls CreateEntity (if it doesn't exist)

    Code (CSharp):
    1.  Entity CreateEntity(UnityObject uobject, int index)
    2.     {
    3.         #if DETAIL_MARKERS
    4.         using (m_CreateEntity.Auto())
    5.         #endif
    6.         {
    7.             int flags = 0;
    8.             if (AddEntityGUID)
    9.                 flags |= k_EntityGUIDMask;
    10.  
    11.             var go = uobject as GameObject;
    12.             if (go != null)
    13.             {
    14.                 if (ForceStaticOptimization || go.GetComponentInParent<StaticOptimizeEntity>() != null)
    15.                     flags |= k_StaticMask;
    16.                 if (!IsActive(go))
    17.                     flags |= k_DisabledMask;
    18.             }
    19.             else if (uobject is Component)
    20.                 throw new ArgumentException("Object must be a GameObject, Prefab, or Asset", nameof(uobject));
    21.  
    22.             var entity = m_DstManager.CreateEntity(m_Archetypes[flags]);
    CreateEntity uses m_DstManager to create entity
     
    Last edited: Nov 12, 2019
    davtam likes this.
  9. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Thanks again, sorry didnt have the source code in front of me and jump on the opportunity to ask.

    What I really want to understand is how this is all handled with sub scenes. I find it extreme difficult to track where entitles exist especially at run time when I change values on a game object.
     
  10. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    The problem you're having is that you're trying to do some very strange things with subscenes and conversion that no one else is doing or has done which means unfortunately no one has any experience to provide help . When you're the first to do something, you kind of have to figure it out yourself.
     
  11. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,709
    Yea fair enough