Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Getting a GameObject's entity from another GameObject during GameObjectToEntity conversion?

Discussion in 'Entity Component System' started by NotaNaN, Dec 26, 2019.

  1. NotaNaN

    NotaNaN

    Joined:
    Dec 14, 2018
    Posts:
    325
    How exactly do you get a reference to the entity a GameObject is going to be converted into from another GameObject (that is being converted) during conversion? I've been pulling my hair out during Christmas trying to figure out how to do this (without making my own dirty, inefficient work around, of course). But there just doesn't seem to be any obvious way to do it... As far as I can tell, at least. In both the GameObjectConversionUtility class and the GameObjectConversionSystem class (and even the EntityManager) I was unable to find a function that takes a GameObject (or any other equivalent piece of information) for an input and in turn returns a corresponding entity!

    So, as of now... I am officially stuck. But I feel like this is supposed to be really easy because entity-to-entity communication is required for any complicated interactions that exist within actual games. Thus, clearly I have just missed something... And, probably something very obvious. If somebody wouldn't mind pointing me in the right direction I would appreciate it greatly.
    Cheers! (Or whatever people say on the forums nowadays...)
     
  2. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    Something like this:
    Code (CSharp):
    1. [RequiresEntityConversion]
    2. public class MoverProxy : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
    3. {
    4.     [SerializeField] private PathProxy _path;
    5.  
    6.     public void Convert(Entity entity, EntityManager entityManager, GameObjectConversionSystem conversionSystem)
    7.     {
    8.         if (_path == null)
    9.         {
    10.             return;
    11.         }
    12.  
    13.         var pathEntity = conversionSystem.GetPrimaryEntity(_path.gameObject);
    14.  
    15.         entityManager.AddComponentData(entity,
    16.             new PathMover {PathEntity = pathEntity});
    17.     }
    18.  
    19.     public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
    20.     {
    21.         if (_path == null)
    22.         {
    23.             return;
    24.         }
    25.  
    26.         referencedPrefabs.Add(_path.gameObject);
    27.     }
    28. }
     
    NotaNaN and PublicEnumE like this.
  3. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    You may also wish to look into GameObjectConversionSystem. These are systems you can write, which run during the conversion process (but after the conversion monobehaviors have been called). You can use Entities.ForEach in these systems to operate on large numbers of monobehavior components, and guarantee that anything that should have been converted in the scene will have an entity counterpart that can be looked up in the GameObjectConversionSystem.

    apologies for omitting code- I am away from a computer right now. Let me know if this isn’t enough detail and I’ll write a more detailed follow up with actual code. :)
     
    NotaNaN likes this.
  4. NotaNaN

    NotaNaN

    Joined:
    Dec 14, 2018
    Posts:
    325
    Hmm... I see! Thanks for the quick response to my question! :D

    I adapted your code snippet to fit my needs... Good news is; I got no errors! Bad news, though, is that the entity references in the DynamicBuffer come out to be null. I'm guessing this is due to me not actually using prefabs for my GameObjects... Would this be the case? :oops:
    Here's the code:
    Code (CSharp):
    1. [RequiresEntityConversion]
    2. public class DestroyQueryAuthoring : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
    3. {
    4.     public void OnEnable() { }
    5.  
    6.     public List<GameObject> gameObjectList;
    7.  
    8.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    9.     {
    10. #if (UNITY_EDITOR)
    11.         if (gameObjectList.Count == 0)
    12.         {
    13.             return;
    14.         }
    15. #endif
    16.  
    17.         var destroyedEntities = dstManager.AddBuffer<DestroyedEntities>(entity);
    18.  
    19.         // Add all targets to be destroyed into the DynamicBuffer.
    20.         for (int i = 0; i < gameObjectList.Count; i++)
    21.         {
    22.             var targetEntity = conversionSystem.GetPrimaryEntity(gameObjectList[i]);
    23.  
    24.             destroyedEntities.Add(new DestroyedEntities
    25.             {
    26.                 Entity = targetEntity
    27.             });
    28.         }
    29.  
    30.     }
    31.  
    32.     public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
    33.     {
    34. #if (UNITY_EDITOR)
    35.         if (gameObjectList.Count == 0)
    36.         {
    37.             Debug.LogError("The gameObjectList within " + gameObject.name + " is isn't filled with anything. TRY AGAIN.");
    38.         }
    39. #endif
    40.         // Declare the referenced GameoObjects.
    41.         for (int i = 0; i < gameObjectList.Count; i++)
    42.         {
    43.             referencedPrefabs.Add(gameObjectList[i]);
    44.         }
    45.     }
    46. }
    .
    .

    You can do WHAT!? I had no idea they mainstreamed the conversion process so that you could write your own runs-after-monobehavior-conversion system! (This is what happens when you stop programing for four months because of school). No worries for the code omittion, although I have to admit I would love to see one of those systems in-code for me to dissect! If you wouldn't mind throwing one my way, I would seriously appreciate you taking the time to do so! :D

    Also... Where are you people getting all your information from? Is there like some crazy ECS-Info hub that I don't know about? It takes a decent amount of doing to find ECS information on the most new and current workflows, do you guys have some kinda secret network or something?
     
    Last edited: Dec 26, 2019
  5. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    Maybe you have to have ConvertToEntity script put on some game object that is ancestor in heirarchy to the game objects you are trying to convert?

    I am not sure, I set this up half a year ago and did not touch it since then.
     
    NotaNaN likes this.
  6. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    You’re on it. :D I just check in and read about whatever topics are in discussion at least once per day. Also helps to read every release note bullet point (for DOTS related package releases). And to spend a lot of time looking through the package source code whenever questions come up. That’s all. :) It’s an exciting time in Unity land.
     
    Last edited: Dec 26, 2019
    NotaNaN likes this.
  7. NotaNaN

    NotaNaN

    Joined:
    Dec 14, 2018
    Posts:
    325
    OOHHHhhhhhh... Figured it out.
    I kinda sorta totally accidentally grabbed references to two not-going-to-be-converted-GameObjects that were for presentation only. My bad. After I targeted appropriate GameObjects everything worked as expected. Thank you for helping me with this, both @Fido789 and @PublicEnumE! Probably should've came to the forums sooner rather than stressing about it over Christmas... By myself. :c

    Well... In that case I've got just about 4.5 months worth of threads to read. (It's going to be great). In all seriousness though, you're right. When I was totally on-the-ball everyday with ECS I never really had these kinds of problems. ;)
    I'll try and refresh myself with the past two weeks and a skim through the whole thing.

    Thank you both for the tips, tricks, and how-to's once again! :D
     
    Last edited: Dec 26, 2019
  8. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    Yeah, it is hard to find resources for this stuff, all is new and rapidly changing. Anyways, I am glad you have it resolved.
     
    NotaNaN likes this.
  9. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    Here's that code example of how this could also be done using a GameObjectConversionSystem. Sometimes IConvertGameObjectToEntity does the job elegantly. But sometimes these systems can prevent the need to do some logistical gymnastics in those MonoBehaviours:

    Code (CSharp):
    1. public struct MyComponent : IComponentData
    2. {
    3.     public Entity referencedEntityInScene;
    4. }
    5.  
    6. public class MyComponent_Authoring : MonoBehaviour, IConvertGameObjectToEntity
    7. {
    8.     public GameObject referencedGameObjectInScene;
    9.  
    10.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    11.     {
    12.         dstManager.AddComponent<MyComponent>(entity);
    13.     }
    14. }
    15.  
    16. [UpdateInGroup(typeof(GameObjectAfterConversionGroup))]
    17. public class MyConversionSystem : GameObjectConversionSystem
    18. {
    19.     protected override void OnUpdate()
    20.     {
    21.         Entities.ForEach((MyComponent_Authoring myComponent_Authoring) =>
    22.         {
    23.             Entity convertedEntity = GetPrimaryEntity(myComponent_Authoring.gameObject);
    24.             MyComponent myComponent = DstEntityManager.GetComponentData<MyComponent>(convertedEntity);
    25.  
    26.             myComponent.referencedEntityInScene = GetPrimaryEntity(myComponent_Authoring.referencedGameObjectInScene);
    27.  
    28.             DstEntityManager.SetComponentData(convertedEntity, myComponent);
    29.         });
    30.     }
    31. }
    I recommend checking out the source for GameObjectConversionSystem. There are several SystemGroups you can hook into there to do work at different stages of the conversion process.

    Anyhow, good luck! Glad you got it sorted.
     
    Last edited: Dec 26, 2019
    NotaNaN likes this.