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 How To Generic ISystem<Component>?

Discussion in 'Entity Component System' started by andreyakladov, Apr 2, 2023.

  1. andreyakladov

    andreyakladov

    Joined:
    Nov 11, 2016
    Posts:
    29
    How does one overcome this error:

    Code (CSharp):
    1. ArgumentException: Unknown Type:`ECS.Systems.EffectTriggerSystem`1[ECS.Components.Effects.EffectSpeed]` All ComponentType must be known at compile time. For generic components, each concrete type must be registered with [RegisterGenericComponentType].
    in:
    Code (CSharp):
    1. fixedStepSimulation.AddSystemToUpdateList(_world.CreateSystem<EffectTriggerSystem<EffectSpeed>>());
    where system:
    Code (CSharp):
    1. public partial struct EffectTriggerSystem<T> : ISystem where T: unmanaged, IEffectTimed
    where component:
    Code (CSharp):
    1. public struct EffectSpeed : IEffectTimed
    where interface:
    Code (CSharp):
    1. public interface IEffect : IComponentData, IEnableableComponent
    If I use this generic in EntityMamanger, like em.GetComponentData<T>(entity) - it works just fine, but throws when I try to use generic ISystem.
    Code (CSharp):
    1. [assembly: RegisterGenericComponentType(typeof(EffectTriggerSystem<EffectSpeed>))]
    has no effect.
     
    Last edited: Apr 2, 2023
  2. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    Generic isystems don’t work right now; it’s on the todo.
     
  3. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    969
    You can try a generic SystemBase for now. It worked in 0.50. Not sure if it works on 1.0. I'm still in the process of upgrading my project.
     
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    Atm. one of work around, but far from ideal as I have experienced, is to tap into System state of ISystem.
     
    Last edited: Aug 9, 2023
  5. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    313
    Edit: Sorry, code posted was not really generic. Removed.
     
    Last edited: Apr 10, 2023
  6. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    Does SystemBase work?
     
  7. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    954
    Yes :)
     
    lclemens likes this.
  8. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    I made generic isystems work in 1.0.8, so enjoy! (Edit: you have to say [assembly: RegisterGenericSystemType(typeof(YourSystem<YourParticularType>))], just like for generic components.)
     
    Last edited: May 19, 2023
  9. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    Generic IJobEntity soon so ? :D
     
  10. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    Mmm that's harder. I'm skeptical personally, but you never know. The people who could do that (i.e. the sourcegenerator people) are currently hard at work trying to bring iteration time down, which I suspect you might prefer...?
     
    Occuros, Sylmerria and Deleted User like this.
  11. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    Um, due to internal process snafus, this apparently did not make it into 1.0.8. Sorry for the confusion! I'm trying to figure out what release it will end up in. :(
     
    lclemens, WAYNGames, bb8_1 and 2 others like this.
  12. farlenkov

    farlenkov

    Joined:
    Mar 28, 2014
    Posts:
    17
    In 1.0.10 I'm trying to use RegisterGenericSystemType like this

    Code (CSharp):
    1. [assembly: RegisterGenericSystemType(typeof(MySystem))]
    And this gives me an error:

    Code (CSharp):
    1. Unity.Entities.CodeGen.EntitiesILPostProcessors: (0,0): error error DC3002: MySystem: [RegisterGenericJobType] requires an instance of a generic value type
    But I don't have any generic job types
     
  13. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    954
    Is your system generic? Like MySystem<T>? Then you also need to declare that in the typeof.
    If not, you just need to register the generic job and not the system.
     
  14. farlenkov

    farlenkov

    Joined:
    Mar 28, 2014
    Posts:
    17
    I have this classes:
    Code (CSharp):
    1. public abstract partial MyBaseSystem<T> : SystemBase
    2.  
    3. public partial MyGameSystem : MyBaseSystem<GameState>
    And I have tried both

    Code (CSharp):
    1. [assembly: RegisterGenericSystemType(typeof(MyBaseSystem<GameState>))]
    2. [assembly: RegisterGenericSystemType(typeof(MyGameSystem))]
    I don't have any generic jobs
     
  15. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    954
    RegisterGenericSystemType is only needed for ISystem.
    SystemBase just needs an implementation and will work.
     
  16. farlenkov

    farlenkov

    Joined:
    Mar 28, 2014
    Posts:
    17
    but if I remove RegisterGenericSystemType I get another error when calling AddSystemManaged:

    Code (CSharp):
    1. ArgumentException: Unknown Type:`MyGameSystem` All ComponentType must be known at compile time. For generic components, each concrete type must be registered with [RegisterGenericComponentType].
     
  17. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    954
    Hm, that's odd that this is thrown.
    I have [DisableAutoCreation] on the base class. When implemented, the system is automatically added so I never need to call AddSystemManaged.
     
  18. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,641
    I confirm that this code now doens't work

    Code (CSharp):
    1.  [DisableAutoCreation]
    2.     public partial class RenderingDOTSPositionSyncEngine:SystemBase
    3. {
    4. }
    5.  
    6. world.AddSystemManaged(new RenderingDOTSPositionSyncEngine());
    7.  
    that's because RenderingDOTSPositionSyncEngine is not found inside the TypeManager stuff and AddSystemManaged now checks for it. I couldn't find a work around yet.
     
  19. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    969
    Do we also need to specify RegisterGenericSystemType for managed generic systems?
     
  20. cf-ie

    cf-ie

    Joined:
    Feb 2, 2022
    Posts:
    13
    Any updates on this?
     
  21. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    230
    Yes, it went in 1.0.10, and got some more fixes later as well.
     
    Antypodish and cf-ie like this.
  22. cf-ie

    cf-ie

    Joined:
    Feb 2, 2022
    Posts:
    13
  23. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    I was using 2022.3.8 and entities 1.0.14. Then I updated to 2022.3.10 and 1.0.16.

    In SystemBase this used to work just fine:

    Code (CSharp):
    1.  
    2. [RequireMatchingQueriesForUpdate]
    3. public abstract partial class EventMonitorBaseSystem<T> : SystemBase where T : unmanaged, IBufferElementData
    4. {
    5.     foreach (var events in SystemAPI.Query<DynamicBuffer<T>>().WithChangeFilter<T>()) {
    6.         for (int i = 0; i < events.Length; i++) { OnEvent(events[i]); }
    7.     }
    8. }
    But now it gives this compile error in Unity:

    The type `T` in `DynamicBuffer<T>`, `UnityEngineComponent<T>`, `RefRO<T>`, `RefRW<T>`, EnabledRefRO<T> and EnabledRefRW<T> can not be a generic Type parameter.


    What changed? How can I fix it?
     
    Last edited: Sep 23, 2023
  24. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    @elliotc-unity Sorry to bug you, but I'm really stuck on this.... Something happened in the latest update and it broke my code above. I tried using an Entities.ForEach() instead but it definitely didn't like that. Are generic types no longer supported in idiomatic foreach? If so, do you have any suggestions for replacements?
     
  25. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    969
    It can be done in SystemBase with IJobChunk.
     
  26. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    760
    Ugh.... that's disappointing. I would much rather use IJobEntity or idiomatic foreach. This seems like a downgrade.
     
  27. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    969
    In our production code, we'd rather avoid the code generated ways like IJobEntity or the different foreaches. This is because it can still change anytime like what happened in your case. Working directly with the generated code is more future proof IMO. It's verbose but it's really not that bad once you get used to it.
     
    lclemens likes this.
  28. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    In current project, we also moving away from idiomatic foreaches.
    Mainly for compilation speed reasons.
    But also they change, and new one's are awful looking:)
     
    lclemens likes this.