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

IConvertGameObjectToEntity vs GameObjectEntity workflow question

Discussion in 'Entity Component System' started by Wolar, Apr 21, 2019.

  1. Wolar

    Wolar

    Joined:
    Sep 25, 2014
    Posts:
    38
    Hello, I'm a little bit confused about current recommended workflows. We are using hybrid approach for some of our stuff because s far as I understand it, we cannot use pure ECS until that stuff works with ECS (for example NavMeshAgent).

    So far we've been using hybrid approach with GameObjectEntities with components being wrapped with ComponentDataProxy or SharedComponentDataProxy. What I have found here on forums is, that this workflow is not really desired and will be sooner or later deprecated. So based on my research we should use MonoBehaviours implementing IConvertGameObjectToEntity with ConvertToEntity components. As long as I use Convert and Destroy, everything works just fine (like in the samples projects). But since I need some stuff that does not supports ECS to be kept on that GameObject, I have tried to use Convert and Inject Game Object. And here comes the problems

    a) I was unable to find any documentation, description or example how "Convert and Inject Game Object" should work. It creates the entity and keeps the game object in the scene but changing data in either of those does not affects the other one. Is this how it's supposed to work?
    b) If a) is the way it works or if should only work in a way Entity => GameObject, is there a way how to edit value of a data in entity? It would be enough to be able to do so in Editor only. What was very convinient when using GameObjectEntity was that it was easy to debug / test as I was able to modify component data or even add component in the editor onto the game object which then reflected that onto the entity. It would be enough to be able to modify entity via Entity Debugger or something like that but I was unable to find any way to do so.

    The only solution I have found for b) was to cache the entity and entity manager created during the conversion process and then have a code that sets the component data when value in the editor on that mono behaviour changes which is not something I'm supposed to do I guess.


    TL;DR How am I supposed / what is the recommended way to use ConvertToEntity with "Convert and Inject Game Object" option selected.

    Thanks for any help / opinions
    Martin
     
  2. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    131
    this is the way I am using its. Not sure its right but I am able to access NavMeshAgent.
    I am can use Convert and Inject option.
    In OnCreateManager, I do an Query for all entity with that attach components and mono-behaviors.(This should be done in OnUpdate if you entities change in number but I am still testing)
    Then I make nativearrays to access the components.

    The Only Issue I have is it renders double meshes on screen. Edit: This is cause by having the HybridRenderer Package installed
    upload_2019-4-23_21-32-59.png
     

    Attached Files:

    Last edited: Apr 24, 2019
    Mikael-H and MrCool92 like this.
  3. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    131
  4. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,223
    Right now I am not aware of a proper way to do a batch convert and inject. If you have a small number of agents, convert and inject is fine. Otherwise, I think most people pool game objects without a convert and inject and then use a reactive systems on their entities to manually grab componentObjects from the pool.

    Proxies are deprecated. Use IConvertGameObjectToEntity interface on a MonoBehaviour to describe groups of component data that should be attached to an entity in an editor-friendly way.

    Runtime editing of entities through the debugger is not supported yet that I am aware of.
     
  5. Wolar

    Wolar

    Joined:
    Sep 25, 2014
    Posts:
    38
    So I think I have figured it out. Thank you DreamersINC, ToComponentArray was probably what I was looking for (I was trying to use ToComponentDataArray which obviously didn't work).

    Another thing I was getting wrong was using of IConvertGameObjectToEntity. I though I have to do both, implement IConvertGameObjectToEntity and add ConvertToEntity component.

    It turned out that IConvertGameObjectToEntity is good only for
    a) Using with Convert and Destroy to create entities instead of MonoBehaviour
    b) Using with Convert and Inject to create additional entities

    What I was getting wrong was that I had for example "HealthMono" MonoBehaviour that was implementing IConvertGameObjectToEntity and creating "Health" ECS component. This would be good with Convert and Destroy but what Convert and Inject does is that it attaches all MonoBehaviour components to the created entity as some kind of ObjectComponent which you can than access (same like the NavMeshAgent) so by doing this I ended up with the new entity having both "HealthMono" and "Health" while I though I had just one thing and was trying to figure out how to display data from "Health" inside "HealthMono" inspector.

    I have also tried (before using ToComponentArray) to use EntityManager.GetComponentObject on each entity which works but I guess is far less performant than iterating array created by ToComponentArray.
     
    Last edited: Apr 25, 2019
  6. wenzhao

    wenzhao

    Joined:
    Oct 28, 2013
    Posts:
    6
  7. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    349
    You can also use fluent API Entities.ForEach() which also supports MonoBehaviours.
    Little example from my project, where MoveVector is IComponentData of an entity and NavMeshAgent is loved by all of us MonoBehaviour class.
    Code (CSharp):
    1. Entities.ForEach((NavMeshAgent navAgent, ref MoveVector moveVector) =>
    2. {
    3.    navAgent.Move(moveVector.value);
    4. });
     
  8. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    969
    We also have the same problem. We used GameObjectEntity because that was what was available at the time. When entity conversion came out, it's not compatible with the way our project is set up. It's so slow. So we're stuck with GameObjectEntity. I don't mind it marked as deprecated. I just hope that it will not be totally removed, or else we can't use the latest versions of Entities.
     
  9. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    131
    You are going to have to stick with 2019 LTS version then. What issue are you having? Maybe I can help
     
  10. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    969
    It's on the link here. It's either GameObjectEntity or overhaul the game such that the conversion system would be used. Overhauling the game is impractical at this point in our game.
     
  11. riskparitygawd

    riskparitygawd

    Joined:
    Sep 22, 2018
    Posts:
    21
    You can get the same functional effect by storing the Entity created in your own AuthoringComponent on a separate monobehaviour after conversion. GameObjectEntity seems to cause issues when used with other entities so I would recommend not relying on it at all.
     
  12. cwennchen

    cwennchen

    Joined:
    Nov 22, 2019
    Posts:
    7
    I still don't understand. When I use GameObjectEntity, I can use the CopyTransformFromGameObjectProxy component to synchronize the GameObject's Transform to LocalToWorld.

    But I can't use CopyTransformFromGameObjectProxy when change to ConvertToEntity, is there any way to synchronize Transform to LocalToWorld?
     
  13. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,753
    For now, you can just create your own IConvertGameObjectToEntity that adds a CopyTransformFromGameObject to your entity.
     
  14. cwennchen

    cwennchen

    Joined:
    Nov 22, 2019
    Posts:
    7
    Oh~, Thanks! so now CopyTransformFromGameObjectProxy is deprecated, but CopyTransformFromGameObjectSystem still works.
     
  15. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    131
    I ended up writing my own transform conversion system and components for ease of use. All the code for it is exposed in the packages
     
  16. jhp129

    jhp129

    Joined:
    Feb 11, 2020
    Posts:
    3
    Can I ask how you were able to create an entity with Navmeshagent component?
    Code (CSharp):
    1. typeof(navmeshagent)
    is this IComponentData or monobehaviour
     
  17. DreamersINC

    DreamersINC

    Joined:
    Mar 4, 2015
    Posts:
    131
    You have to convert and inject game object as NavMeshAgent is a mono behavior. This means it cannot be used in burst jobs or pure ecs. However if you want to use pure ecs, there is a low level NavmeshAgent API that you want write your own navmesh system with.

    Code (CSharp):
    1. Entities.ForEach((NavMeshAgent Agent) =>{ // code here})