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

[SOLVED] Can't Inject ComponentArray (InjectComponentGroup.cs)

Discussion in 'Entity Component System' started by mgmhunt, Sep 6, 2018.

  1. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    61
    So I'm getting an exception at line 240 of InjectComponentGroup.cs (Entities Package 0.0.12 preview.12)

    Code (CSharp):
    1.  $"{system.GetType().Name}:{groupField.Name} [Inject] may only be used on ComponentDataArray<>, ComponentArray<>, TransformAccessArray, EntityArray, {string.Join(",", InjectionHookSupport.Hooks.Select(h => h.FieldTypeOfInterest.Name))} and int Length.";
    Looking at the code beforehand when it's iterating through the field types, I can't see any valid check for ComponentArray<> ... ????... so it falls to exception as expected??

    Code (CSharp):
    1. if (field.FieldType.IsGenericType &&
    2.  field.FieldType.GetGenericTypeDefinition() == typeof(ComponentDataArray<>))
    3.                 {
    4. ...
    5.                 }
    6. else if (field.FieldType.IsGenericType &&
    7. field.FieldType.GetGenericTypeDefinition() == typeof(SubtractiveComponent<>))
    8.                 {
    9.                     ...
    10.                 }
    11. else if (field.FieldType.IsGenericType &&
    12. field.FieldType.GetGenericTypeDefinition() == typeof(BufferArray<>))
    13.                 {
    14. ...
    15.                 }
    16. else if (field.FieldType.IsGenericType &&
    17. field.FieldType.GetGenericTypeDefinition() == typeof(SharedComponentDataArray<>))
    18.                 {
    19. ...
    20.                 }
    21. else if (field.FieldType == typeof(EntityArray))
    22.                 {
    23. ..
    24.                 }
    25. else if (field.FieldType == typeof(int))
    26.                 {
    27.                     if (field.Name != "Length" && field.Name != "GroupIndex")
    28. ...
    29.                 }
    30. else
    31.                 {
    32. return $"{system.GetType().Name}:{groupField.Name} [Inject] may only be used on ComponentDataArray<>, ComponentArray<>, TransformAccessArray, EntityArray, {string.Join(",", InjectionHookSupport.Hooks.Select(h => h.FieldTypeOfInterest.Name))} and int Length.";
    33.  
    I'm following the syntax of the examples and all other injections are working fine, but ComponentArray's aren't... and debugging the code it's looks like they never will...?? Went back a few versions of the packages and the code didn't change.

    Can someone explain how to inject Component Array via the usual method

    Code (CSharp):
    1.         public struct Data
    2.         {
    3.             public readonly int Length;
    4.             public ComponentArray<Collider> myCollider
    5.             public EntityArray Entity;
    6.         }
    7.  
    8.         [Inject] private Data data;
    I'm seeing this in the examples and from the documentation but can't see how this would ever work stepping through the code?
     
  2. MartijnGG

    MartijnGG

    Joined:
    May 3, 2018
    Posts:
    74
    Support for the ComponentArray is added automatically through those InjectionHookSupport.Hooks thought Unity.Entities.Hybrid.
    Did you perhaps disable the automatic system bootstrap?
     
    mgmhunt likes this.
  3. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    61
    Spot on! Awesome thanks, yes I'm manually creating the worlds/managers and skipped over that section of the AutoBootstrap... will give script a closer look! cheers
     
  4. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    61
    OK after looking at this a bit further. I've manually injected the hooks but had to add the line

    [assembly: InternalsVisibleTo("Assembly-CSharp")]

    to the AssemblyInfo.cs file under Unity.Entities.Hybrid to to get around:

    'GameObjectArrayInjectionHook' is inaccessible due to its protection level (CS0122)
    'TransformAccessArrayInjectionHook' is inaccessible due to its protection level (CS0122)
    'ComponentArrayInjectionHook' is inaccessible due to its protection level (CS0122)

    Any better suggestions as this means hacking the package?
     
    Last edited: Nov 12, 2018
  5. MartijnGG

    MartijnGG

    Joined:
    May 3, 2018
    Posts:
    74
    Instead of this, you can also use Reflection to get these 3 functions. A bit hacky, but sadly needed if you want Hybrid support without the DefaultWorld
     
    mgmhunt likes this.
  6. mgmhunt

    mgmhunt

    Joined:
    Apr 1, 2013
    Posts:
    61
    Code (CSharp):
    1. Assembly unityEntitiesAssembly = Assembly.Load("Unity.Entities.Hybrid, Version=0.0.0.0");
    2. Type hookType;
    3. hookType = unityEntitiesAssembly.GetType("Unity.Entities.GameObjectArrayInjectionHook");
    4. InjectionHookSupport.RegisterHook(Activator.CreateInstance(hookType) as InjectionHook);
    5. hookType = unityEntitiesAssembly.GetType("Unity.Entities.TransformAccessArrayInjectionHook");
    6. InjectionHookSupport.RegisterHook(Activator.CreateInstance(hookType) as InjectionHook);
    7. hookType = unityEntitiesAssembly.GetType("Unity.Entities.ComponentArrayInjectionHook");
    8. InjectionHookSupport.RegisterHook(Activator.CreateInstance(hookType) as InjectionHook);
     
    Last edited: Nov 18, 2018