Search Unity

EntityQuery and several different NativeArray.

Discussion in 'Entity Component System' started by AlexandrBuryakov, Jul 31, 2019.

  1. AlexandrBuryakov

    AlexandrBuryakov

    Joined:
    May 30, 2018
    Posts:
    31
    Hello.
    There are entities which have A,B,C,D components. There are other entities which have A,B,C,E components. I need to create two arrays of component A.
    The first should consist of entities at which there are D and E components.
    The second should consist of entities at which there are components D.
    At the same time whether it is possible to make so that their indexes matched?
    For example:
    [ A(d), A(d), A(d), A(d) ]
    [ A(d), A(d), A(d), A(d), A(e), A(e), A(e) ]

    There is such assumption:
    Code (CSharp):
    1.  
    2.        EntityQuery m_GroupFirst = GetEntityQuery (
    3.             new EntityQueryDesc {
    4.                 All = new ComponentType [] {
    5.                     ComponentType.ReadWrite<ComponentA> (),
    6.                     ComponentType.ReadWrite<ComponentB> (),
    7.                     ComponentType.ReadWrite<ComponentC> (),
    8.                     ComponentType.ReadWrite<ComponentD> (),
    9.                 },
    10.                 //Any = new ComponentType [] {},
    11.                 //None = new ComponentType [] {},
    12.             }
    13.         );
    14.  
    15.        EntityQuery m_GroupSecond = GetEntityQuery (
    16.             new EntityQueryDesc {
    17.                 All = new ComponentType [] {
    18.                     ComponentType.ReadWrite<ComponentA> (),
    19.                     ComponentType.ReadWrite<ComponentB> (),
    20.                     ComponentType.ReadWrite<ComponentC> (),
    21.                     ComponentType.ReadWrite<ComponentD> (),
    22.  
    23.                 },
    24.                 Any = new ComponentType [] {
    25.                     ComponentType.ReadWrite<ComponentE> (),
    26.                 },
    27.                 //None = new ComponentType [] {},
    28.             }
    29.         );
    30.  
    31.     protected override JobHandle OnUpdate ( JobHandle inputDeps ) {
    32.  
    33.         var arrayFirst = m_GroupFirst.ToComponentDataArray<ComponentA> ( Allocator.TempJob );
    34.         var arraySecond = m_GroupSecond.ToComponentDataArray<ComponentA> ( Allocator.TempJob );
    35.  
    On how many this correct solution?
    Can perhaps make through one EntityQuery, but not two?
     
    Last edited: Jul 31, 2019
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    I'm not sure why you need this but I can't think of a solution that'd just naturally do it that way. I'd probably just create a single query and generate the arrays myself.

    For example, I'd do this in a job but here's an example just using ForEach to explain what I mean.

    Code (CSharp):
    1.             // Do this is in a job it'd be very fast.
    2.             var listFirst = new NativeList<ComponentA>(Allocator.TempJob);
    3.             var listE = new NativeList<ComponentA>(Allocator.TempJob);
    4.  
    5.             this.Entities.WithAll<ComponentB, ComponentC, ComponentD>().ForEach((Entity entity, ref ComponentA a) =>
    6.             {
    7.                 if (this.EntityManager.HasComponent<ComponentE>(entity))
    8.                 {
    9.                     listE.Add(a);
    10.                 }
    11.                 else
    12.                 {
    13.                     listFirst.Add(a);
    14.                 }
    15.             });
    16.  
    17.             var arrayFirst = listFirst.AsArray();
    18.             var arraySecond = new NativeArray<ComponentA>(listFirst.Length + listE.Length, Allocator.TempJob);
    19.  
    20.             NativeArray<ComponentA>.Copy(arrayFirst, 0, arraySecond, 0, arrayFirst.Length);
    21.             NativeArray<ComponentA>.Copy(listE.AsArray(), 0, arraySecond, listFirst.Length, listE.Length);
    22.  
    23.            
    Not tested~

    there is a much cleaner way if ComponentE is only ever accompanied by ABCD as well, but breaks down if it has a separate archetype.
     
    Last edited: Jul 31, 2019
  3. AlexandrBuryakov

    AlexandrBuryakov

    Joined:
    May 30, 2018
    Posts:
    31
    Thanks a lot.
    Most likely "EntityManager.HasComponent <ComponentE>(entity))" will solve my problem.


    Added later:
    Though many not necessary admissions turn out.
    And in a case with sorting it will not turn out to write in components because, it seems, indexes of arrays and components differ.
     
    Last edited: Aug 1, 2019