Search Unity

Feature Request Support for generic components with ghost

Discussion in 'NetCode for ECS' started by Jawsarn, Jan 23, 2023.

  1. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    245
    At the moment something like this will break the generator

    Code (CSharp):
    1. [assembly: RegisterGenericComponentType(typeof(GameplayAttribute<Health>))]
    2.  
    3.     public struct GameplayAttribute<T> : IComponentData
    4.     {
    5.         [GhostField]
    6.         public float currentValue;
    7.         [GhostField]
    8.         public float baseValue;
    9.     }
     
  2. CMarastoni

    CMarastoni

    Unity Technologies

    Joined:
    Mar 18, 2020
    Posts:
    894
    The reason why we aren't supporting them is mostly due to the fact we didn't have a concrete use case that was really justifying the need to add such a support.

    This case too is actually also pretty niche. I imagine you have something like

    Code (csharp):
    1.  
    2. enum AttribType
    3. {
    4.    Health,
    5.   ...
    6. }
    7. or
    8. struct Health
    9. {}
    10.  
    11. struct GameplayAttribute<T>
    12. {
    13.     [GhostField]
    14.     public float currentValue;
    15.     [GhostField]
    16.     public float baseValue;
    17. }
    18.  
    So that you can easily from an entity or filtering (like in the following example or similar patterns)
    Code (csharp):
    1.  
    2. foreach(var (health, ent) in SystemAPI.Query<RefRW<GameplayAttribute<Health>>>()
    3. {
    4.    health.ValueRW += xx;
    5. }
    6. [code]
    7.  
    8. This is a classic use for gameplay purpose. The generic is used just to distinguish the type, and make sense (from a code duplication perspective). However, can be easily changed (sometime for the better) to use different components directly instead of using a generic clause like  GameplayAttribute<XXX>, given the fact is not adding or providing any advantage at runtime (you always need to specify anyway the concrete implementation in all cases).
    9. In most cases also, the final game design may end up adding extra field on some of the attribute, depeding on the property type. So, especially if you have a large number of this property, the saved space then can be consistent (unused fields).
    10.  
    11. Unfortunately, also, this pattern leads to a tons of serialiser (1 per component type) even though they all do the same things. That generate quite a of code bloat.
    12.  
    13. The ideal serialization solution for this kind of scenario is to generate just one of them (for the generic class) and map all the concrete instances to use these serialization functions.
    14. It is an actually somewhat doable, since we can detect that use case. Of course need some work.
    15.  
    16. I think support for generic component make sense in general, even though we may need to add some constraint.
     
  3. Jawsarn

    Jawsarn

    Joined:
    Jan 12, 2017
    Posts:
    245
    Thank you for the reply and insight!

    I don't use enums but derive it from SOs in authoring, but general concept is correct. Currently I'm using interfaces and generating the concrete implementaitons as a workaround, but good point it is creating unecessary serialiezers.