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

Question Clarification of Hybrid changes in 1.0?

Discussion in 'Entity Component System' started by staringatlights, Dec 17, 2022.

  1. staringatlights

    staringatlights

    Joined:
    Sep 1, 2013
    Posts:
    29
    I'm looking for some clarification on the changes to the hybrid workflow from 0.51 to 1.0.

    I've been told the "hybrid" gameobject-linked-to-entity workflow is gone.

    I'm used to the SubScene workflow as well as the ConvertToEntity workflow from before where we could choose to not destroy the GameObject. I believe a CompanionLink would be created and the entity would sync its transform to the GameObject every frame.

    I see that we still have "Companion Game Object Update Transform System" in 1.0. Is that kind of functionality still available?

    I could do something like this to manually create a CompanionLink to a GO via Baking:

    Code (CSharp):
    1.     public class TextMeshHybrid : MonoBehaviour
    2.     {
    3.         public GameObject textMeshGO;
    4.     }
    5.  
    6.     public class TextMeshHybridData : IComponentData
    7.     {
    8.         public TextMeshPro textMesh;
    9.     }
    10.  
    11.     public class TextMeshBaker : Baker<TextMeshHybrid>
    12.     {
    13.         public override void Bake(TextMeshHybrid authoring)
    14.         {
    15.             AddComponentObject(new CompanionLink()
    16.             {
    17.                 Companion = authoring.textMeshGO
    18.             });
    19.         }
    20.     }
    But this now requires me to manage 2 separate objects in the hierarchy. I would prefer the older workflow where the entity would be converted and made hybrid automatically, so I only have to position one object in my scene instead of two. Is that still possible?

    --

    My use case is TextMeshPro. I used to put TextMeshPro GameObject's in my ECS subscenes and they would convert to hybrid entities automatically (I think anyway). When inspected, the entity would have a RenderMesh and a "Hybrid Chunk Info" component. I'm not actually sure if it was hybrid or if TMP converted fully to an entity in 0.51. (As an aside, TMP only works if you add version 3.2.0 and use the SRP shaders).

    In 1.0, using the same workflow of putting TMP on a GameObject and putting it in an ECS subscene, I get the following error: "Renderer is not converted because either the assigned mesh is null or no materials are assigned on GameObject Text (TMP)." and the converted entity has no RenderMesh nor Hybrid Chunk Info.
     
  2. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    This is an excellent question. It seems like some functionality has been lost in 1.0. I too would like to know if there is a way to synchronize transforms on gameobjects that don't appear in the officially-supported game-object-type list. Maybe every developer must write their own GO/Entity transform sync systems??
     
  3. TheOtherMonarch

    TheOtherMonarch

    Joined:
    Jul 28, 2012
    Posts:
    862
    I handle my own syncing to game objects. Object pooling is very important in GameObject land. Right now they still support linking if you are using officially-supported game-object-types.

    If they do support a new GameObject entity link system. I would like if

    1: Only one way of doing things.
    2: Has support for object pooling.
    3: Can easily be excluded so you can have multi-worlds where you want to separate graphics from a pure ECS physics sim.
     
    lclemens likes this.
  4. staringatlights

    staringatlights

    Joined:
    Sep 1, 2013
    Posts:
    29
    So I've tried a few different approaches to recreating the hybrid approach:

    1. Attempt to bind a TextMeshPro component as a component object on the entity in the Baker:

    Code (CSharp):
    1. public class TextMeshHybrid : MonoBehaviour
    2.     {
    3.     }
    4.  
    5.     public class TextMeshHybridData : IComponentData
    6.     {
    7.         public TextMeshPro textMesh;
    8.     }
    9.  
    10.     public class TextMeshBaker : Baker<TextMeshHybrid>
    11.     {
    12.         public override void Bake(TextMeshHybrid authoring)
    13.         {
    14.             AddComponentObject(new TextMeshHybridData()
    15.             {
    16.                 textMesh = authoring.gameObject.GetComponent<TextMeshPro>()
    17.             });
    18.         }
    19.     }
    The result is the same error at runtime and no rendering of the text: Renderer is not converted because either the assigned mesh is null or no materials are assigned on GameObject Text (TMP).

    This brings up another important question: How do I know what built-in Unity components are going to convert and which aren't? Is there a list somewhere? Entities Graphics has this list, are there others?



    2. I also tried to directly recreate the old hybrid entities approach via CompanionLink to the GameObject being baked:

    Code (CSharp):
    1.     public class TextMeshHybrid : MonoBehaviour
    2.     {
    3.     }
    4.  
    5.     public class TextMeshBaker : Baker<TextMeshHybrid>
    6.     {
    7.         public override void Bake(TextMeshHybrid authoring)
    8.         {
    9.             AddComponentObject(new CompanionLink()
    10.             {
    11.                 Companion = authoring.gameObject
    12.             });
    13.            
    14.         }
    15.     }
    But the GameObject is deleted from the hierarchy upon placing it inside a subscene.

    So the question remains. Is the ability to author a linked GameObject AND entity at the same time from a single GameObject inside the editor gone? Keeping the GameObject around is no longer an option, and would require syncing transforms with a completely separate GameObject outside of the subscene?

    Does this mean I can only place GameObjects in my subscene that completely convert every component to ECS? Or am I only running into this issue because TextMeshPro doesn't convert properly right now?
     
  5. Ryunis

    Ryunis

    Joined:
    Dec 23, 2014
    Posts:
    24
    I would also like to know what the recommended alternative to the old hybrid approach is. I have an older project that I want to update to 1.0, however I can't see how to do that without it being a massive pain in the ***. As far as I can tell hybrid scenes aren't a thing anymore, but that's the approach I would very much want for my use case.
     
    lclemens likes this.
  6. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    When you say "I handle my own syncing to game objects" does that mean you wrote a system that runs on the main thread and constantly copies transform data from entities to game-objects? Forcing every developer to write their own flavor of a system like this sounds like a recipe for a good time.
     
    Envilon likes this.
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Hybrid approach is pretty much gone if you're using GO's in a subscene.
    Alternative is to not bake hybrid GO's in the subscenes at all.

    For that purpose, use some kind of runtime authoring (and just use default scenes)

    Or... you can always use already existing free implementations;

    Like TransformContainer that is used for sync'ing both ways to Entity and backwards to Transform.


    Sync'ing what you need it not that hard. Its pretty much an IJobParallelForTransform job.
    TransformAccessArray management is bit tricky to make efficient.

    Though worth mentioning that existing Unity's hybrid transform solution is worse than a custom in terms of allocation & performance.

    So its a win-win if you go for a custom solution that suits your specific game anyway.
     
    Last edited: Dec 21, 2022
  8. staringatlights

    staringatlights

    Joined:
    Sep 1, 2013
    Posts:
    29
    Thanks for clarification Vergil.

    One of my biggest remaining questions is about placing objects in the world using the scene editor. We need a GO to place objects, and for them to become objects we need to put them in a subscene and bake them.

    Its my understanding that during conversion all of the components that can be converted will. Transform, mesh, etc. all convert automatically.

    But it's hard to know what Unity components will bake automatically. TextMeshPro does not, TextMesh does. How can we know what components will bake? What happens when a GO has a component that does not convert? Is that component dropped or perhaps automatically added as a componentobject?
     
  9. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    988
    You can look at the CompanionComponentSupportedTypes file to see what types are automatically baked to entities.

    If there are not there and you don't bake them yourself they will be dropped.
     
  10. staringatlights

    staringatlights

    Joined:
    Sep 1, 2013
    Posts:
    29
    Thanks for that WAYN_Games that is super helpful. So if I understand correctly the ECS subscene is really an all or nothing approach. Since everything in the subscene is converted with the Entities package installed, I guess you cant have GOs inside a subscene at all?
     
  11. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    988
    No, all you can do is reference a prefab go on a class IComponentData and instantiate that GO at runtime.
     
    contact_unity103 likes this.