Search Unity

how to mount GameObject or its component(like MeshRenderer, NavAgent) to the exist entity

Discussion in 'Graphics for ECS' started by wang37921, Nov 22, 2018.

  1. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    create entity first, no appearance now.
    and update its position. (one system update it position)
    while it in view range, stage it.(system check its position and stage it into sene)
    inst a GameObject from Prefab(include MeshRenderer and NavAgent and so on, classic MonoBehaviours).
    I wanna to know how to mount this GameObject or some of its component(like MeshRenderer, NavAgent) to the exist entity.
     
  2. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    I view the entity package.
    GameObjectEntity support build the entity from GameObject, so I begin with it.
    And got this function EntityManager::SetComponentObject(Entity entity, ComponentType componentType, object componentObject)
    it seems like can satisfy my requirement: mount exist GameObject's component to exist entity.
    but it is internal method.
    Can it solved now? Can public this method later?

    OR the thinking direction wrong?

    Is this method feasible?
    Instantiate the GameObject, Add GameObjectEntity into the gameobject, then copy the exist Entity's ComponentData into the new GameObject's Entity and Destroy the old entity?

    @MartinGram Any advise, thanks
     
  3. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    wang37921 likes this.
  4. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
  5. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    arrange it.
    but in real project, need consider the gameobject's destroy. if not control the gameobject's life circle carefully, better add a Monobehaviour do the things.(eg. change scene directly, not manual remove gameobject's component from the entity before destroy gameobject)

    Code (CSharp):
    1.  
    2. public static class EntityGameObjectExtensions
    3. {
    4.     private static Action<EntityManager, Entity, ComponentType, object> _setComponentObject;
    5.  
    6.     public static void AddComponentToEntity(this GameObject gameobject, Entity entity, params Type[] classicComponents)
    7.     {
    8.         if (_setComponentObject == null)
    9.         {
    10.             var methodInfo = typeof(EntityManager).GetMethod(
    11.                 "SetComponentObject",
    12.                 BindingFlags.NonPublic | BindingFlags.Instance
    13.             );
    14.  
    15.             if (methodInfo == null)
    16.                 throw new NullReferenceException("SetComponentObject changed");
    17.             _setComponentObject = (Action<EntityManager, Entity, ComponentType, object>)Delegate.CreateDelegate(typeof(Action<EntityManager, Entity, ComponentType, object>), null, methodInfo);
    18.         }
    19.         var entityManager = World.Active.GetExistingManager<EntityManager>();
    20.  
    21.         foreach (var componentType in classicComponents)
    22.         {
    23.             var component = gameobject.GetComponent(componentType);
    24.             if (!entityManager.HasComponent(entity, componentType))
    25.                 entityManager.AddComponent(entity, componentType);
    26.             _setComponentObject.Invoke(entityManager, entity, componentType, component);
    27.         }
    28.     }
    29. }
     
    Last edited: Nov 22, 2018
  6. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    The reason it's setup weird like that in my original post is I actually have a bunch of reflection methods I just setup all at once that aren't included in that code snippet. So the Setup() method has a lot more in there.

    (Also I force myself to use stylecop these days)
     
    wang37921 likes this.
  7. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    just personal bad habit(programmer...), you support the solution and it is ingenious. thank you
     
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    A few things to note which are wrong in my original post.

    You can totally just use AddComponent(Entity, Type) to add a ComponentObject after entity is created. Doesn't need to be part of the archetype.

    You can use Entity.GetComponentObject to use with chunk iteration.
     
  9. wang37921

    wang37921

    Joined:
    Aug 1, 2014
    Posts:
    102
    so kind, thank you for your advice;)