Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

What is the right way to fine tune gameobject conversion?

Discussion in 'Entity Component System' started by SubPixelPerfect, Oct 27, 2019.

  1. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    I'm using my own 2d rendering system that does not use Translation, Rotation and LocalToWorld components, instead, I have Position2D, Rotation2D, and LocalToCanvasMatrix3x2, so I need to configure conversion not to create standard transformation components, what is the right approach here?

    Another example:
    To avoid this bug, I need to remove prefab component form my prefab-entities and to hide them in another way
    ( prefab entities don't have WorldRenderBounds and when you instantiate a prefab buggy function is invoked, what make new instances be placed one per chunk )

    But I can't find a good way to remove the Prefab component using a conversion system.
    The moment when the Convert method of IConvertGameObjectToEntity is invoked is before the Prefab component added to the entity, so I can't nither remove it nor prevent its creation...

    What i'm doing is removing prefab after sub-scene load,
    I wonder is there some way to better control the conversion process.
     
    Last edited: Oct 27, 2019
    NotaNaN likes this.
  2. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    As @Joachim_Ante said in this thread https://forum.unity.com/threads/701909/
    there are no plans for editor tools to directly construct/edit entities or entity-prefabs

    So i'm looking for a way to be able to construct anything using conversion workflow...
     
    Last edited: Oct 27, 2019
    NotaNaN likes this.
  3. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    One more case:
    Not all entities in the game are renderable objects, some of them just data containers,
    For example, in my game each level has, it's own goal like "get # points to win", "kill # enemies", or "find item X"
    I have an entity that holds the level goal data, I want to be able to construct and configure it using editor with nice sliders and checkboxes.

    GameObject conversion system crates Translation, Rotation, and LocalToWorld which i'm never going to use so that components going to simply waste space in the chunk
    (not a big deal, but it makes me feel bad when I know that there is garbage in my data... :) )

    Maybe I'm missing something but there for sure must be a way to avoid transform conversion...
     
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,626
    IConvertGameObjectToEntity should really only be used for adding components.

    If you need to remove components or add a component back that hasn't been added (for example Unity Physics adding translation/rotation back to static objects) you can use a GameObjectConversionSystem that updates after the transform conversion system.
     
  5. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    @tertle thank you for your answer
    trying to do it but got some difficulties

    I have a game object with a list of prefabs i'm going to need at runtime as entities
    All my prefabs have PrefabAuth MonoBehaviour attached
    I'm using DeclareReferencedPrefabs to enqueue them for conversion:
    Code (CSharp):
    1. public class PrefabAuth:MonoBehaviour{}
    2. public class ConversionTest : MonoBehaviour,IConvertGameObjectToEntity,IDeclareReferencedPrefabs{
    3.   public List<GameObject> prefabs;
    4.   public void DeclareReferencedPrefabs( List<GameObject> referencedPrefabs ){
    5.     referencedPrefabs.AddRange( prefabs);
    6.   }
    7.   public void Convert( Entity e, EntityManager em, GameObjectConversionSystem conversionSys ){  }
    8. }
    next i'm iterating those prefabs after conversion
    Code (CSharp):
    1. [UpdateInGroup(typeof(GameObjectAfterConversionGroup))]
    2. public class PostConvSys : GameObjectConversionSystem{
    3.   protected override void OnUpdate(){
    4.     Entities.WithAll<PrefabAuth>().ForEach( ( Entity prefab ) => {
    5.       Debug.Log( "Translation exists: " + DstEntityManager.HasComponent<Translation>( prefab ) );
    6.     });
    7.   }
    8. }
    output is:
    Code (csharp):
    1. Translation exists: False
    2. Translation exists: True
    3. Translation exists: True
    4. Translation exists: False
    so some of them already converted but some aren't yet...
    is there a way to make the post-conversion system run when everything is converted?
     
    Last edited: Oct 28, 2019
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    You are mixing the entities of the conversion world with the entities of the destination world. You want this:
    Code (CSharp):
    1. [UpdateInGroup(typeof(GameObjectAfterConversionGroup))]
    2.     public class PostConvSys : GameObjectConversionSystem
    3.     {
    4.         protected override void OnUpdate()
    5.         {
    6.             Entities.ForEach((PrefabAuth auth) => {
    7.                 Debug.Log("Translation exists: " + DstEntityManager.HasComponent<Translation>(GetPrimaryEntity(auth)));
    8.             });
    9.         }
    10.     }
     
  7. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    @DreamingImLatios good catch yes now I can see the translation on those entities,
    but I still don't see the prefab component there... :/
     
  8. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    It happens after the AfterGameObjectConversionGroup. See GameObjectConversionUtility.cs line 158 as of Entities 0.1.1.
     
    SubPixelPerfect likes this.
  9. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    So, to summarize, the answers to questions i've asked at the topic start:

    Q: Is it possible to configure conversion not to create standard transformation components?
    A: You can't prevent automatic transform component conversion, the best thing you can do is to clean up garbage after conversion system :|

    Q. How to remove the Prefab component using a conversion system?
    A. You can't remove prefab component from prefab-entity during conversion, to convert GameObject-prefab to non-prefab-entity you have to instantiate it before conversion :|
     
  10. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,574
    1. As already know, I think best is to follow children tree and remove relevant components, like rotation, etc., after prefab is created.

    2. After you create and modify prefab entity, you should not touch it, other than for instantiation of new entities.

    I don't see reason, why you would need direct prefab in system, as that is your template, to instantiate proper workable by systems entities? Maybe if you explain better your use case?

    I really like concept of prefab component in entities, that they are ignored by systems. Prevents from range of potential issues. Specially when destroying entities.

    You can view them in entity debugger, even if instances are not created, from these prefab yet.
     
  11. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    I've already explained my case:
    There is a bug that makes an entity that was instantiated from a prefab each time be placed in a new chunk.
    So if I have a Prefab component on my instantiation-source-entity I end up with 10000 chunks for 10000 small entities...
    As a temporary workaround, until it'll be fixed, i'm removing the Prefab component and hiding my instantiation-source-entity by moving it outside of camera frustum.
     
  12. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,574
    I see, fair enough.