Search Unity

Tell ECS [Inject] that I am not even reading some stuff

Discussion in 'Entity Component System' started by Guedez, Dec 29, 2018.

  1. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    For instance this system:
    Code (CSharp):
    1. [UpdateBefore(typeof(AddItemToInventory))]
    2. public unsafe class DestroyStage2ItemSystem : ComponentSystem {
    3.     struct UseItemSystemGroup {
    4.         public ComponentDataArray<DestroyItem> dest;
    5.         public EntityArray Entity;
    6.         public readonly int Length;
    7.     }
    8.     [Inject] UseItemSystemGroup query;
    9.     protected unsafe override void OnUpdate() {
    10.         for (int i = 0; i < query.Length; i++) {
    11.             PostUpdateCommands.DestroyEntity(query.Entity[i]);
    12.         }
    13.     }
    14. }
    I don't even read the value or access in any way the DestroyItem component. Is there a similar attribute to "ReadOnly" that would tell "I am not even going to read this"
     
  2. IsaiahKelly

    IsaiahKelly

    Joined:
    Nov 11, 2012
    Posts:
    418
    The problem with using [Inject] is that it does a bunch of things automatically for you that actually hurt performance. Take a look at this ECS Talk for more info on the subject. So Unity is actually planing to remove that attribute in the future.

    What you want to do here is create the component group yourself instead of using injection. So you can better control what data you pull from the entities.

    Code (CSharp):
    1. using Unity.Entities;
    2.  
    3. public class DestroySystem : ComponentSystem
    4. {
    5.     // Define component group variable instead of struct.
    6.     private ComponentGroup m_DestroyGroup;
    7.  
    8.     protected override void OnCreateManager()
    9.     {
    10.         // Manually create the component group on startup.
    11.         m_DestroyGroup = GetComponentGroup(ComponentType.ReadOnly<Destroy>());
    12.     }
    13.  
    14.     protected override void OnUpdate()
    15.     {
    16.         // Get only the component arrays you actually need in update.
    17.         var entities = m_DestroyGroup.GetEntityArray();
    18.  
    19.         for (int i = 0; i < entities.Length; i++)
    20.         {
    21.             PostUpdateCommands.DestroyEntity(entities[i]);
    22.         }
    23.     }
    24. }
    This code will prevent the creation of a Destroy component array because you have to actually get them yourself in OnUpdate.
     
    Last edited: Dec 29, 2018
    Guedez likes this.
  3. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    That level of customization is possible with EntityArchetypeQuery and chunk iteration.. you can add some queries so you ensure the component you want are included, but don't use `ArchetypeChunkComponentType` for that type you are not going to read.
     
    Guedez likes this.