Search Unity

Resolved EntityQuery Cache for CalculateEntityCount returning wrong values

Discussion in 'Entity Component System' started by charleshendry, Feb 2, 2020.

  1. charleshendry

    charleshendry

    Joined:
    Jan 7, 2018
    Posts:
    98
    Hi,

    I have a ComponentSystem that links to the UI where I want it to display the entity count based on an EntityQuery. I have two entity queries created in OnCreate, both use a SetSharedComponentFilter. Then whenever the system updates (triggered by an event Entity), I use CalculateEntityCount on each of the two queries.

    However, the numbers returned are wrong as the 1st query shows the same number as the 2nd query. If I re-define the queries in OnUpdate, then the numbers are correct. Is a query cache like this not allowed, or am I doing something else wrong?

    Code (CSharp):
    1. using Unity.Collections;
    2. using Unity.Entities;
    3.  
    4. public class AgentAssignStatusSystem : ComponentSystem
    5. {
    6.     private EntityQuery assignQuery, associatesPoolQuery, soldiersPoolQuery;
    7.  
    8.     protected override void OnCreate()
    9.     {
    10.         assignQuery = GetEntityQuery(ComponentType.ReadOnly<MafiaAssignStatusComponent>());
    11.         RequireForUpdate(assignQuery);
    12.  
    13.         SetPoolNumQueries();
    14.     }
    15.  
    16.     protected override void OnUpdate()
    17.     {
    18.         NativeArray<MafiaAssignStatusComponent> data = assignQuery.ToComponentDataArray<MafiaAssignStatusComponent>(Allocator.TempJob);
    19.         NativeArray<Entity> agents = assignQuery.ToEntityArray(Allocator.TempJob);
    20.  
    21.         for (int i = 0; i < data.Length; i++)
    22.         {
    23.             EntityManager.SetSharedComponentData(agents[i], new MafiaStatusComponent { Status = data[i].Status });
    24.         }
    25.  
    26.         UpdatePoolNumUI();
    27.         EntityManager.RemoveComponent<MafiaAssignStatusComponent>(assignQuery);
    28.  
    29.         agents.Dispose();
    30.         data.Dispose();
    31.     }
    32.  
    33.     private void UpdatePoolNumUI()
    34.     {
    35.         int val1 = associatesPoolQuery.CalculateEntityCount(); // equals 4 (incorrect)
    36.         int val2 = soldiersPoolQuery.CalculateEntityCount(); // equals 4 (correct)
    37.      
    38.         EntityQuery query1 = GetEntityQuery(ComponentType.ReadOnly<MafiaStatusComponent>(), ComponentType.ReadOnly<MafiaTypeComponent>());
    39.         query1.SetSharedComponentFilter(new MafiaStatusComponent { Status = AgentMafiaStatus.Pool }, new MafiaTypeComponent { Type = AgentMafiaType.Associate });
    40.         int a0 = query1.CalculateEntityCount();  // equals 10 (correct)
    41.  
    42.         EntityQuery query2 = GetEntityQuery(ComponentType.ReadOnly<MafiaStatusComponent>(), ComponentType.ReadOnly<MafiaTypeComponent>());
    43.         query2.SetSharedComponentFilter(new MafiaStatusComponent { Status = AgentMafiaStatus.Pool }, new MafiaTypeComponent { Type = AgentMafiaType.Soldier });
    44.         int s0 = query2.CalculateEntityCount(); // equals 4 (correct)
    45.     }
    46.  
    47.     private void SetPoolNumQueries()
    48.     {
    49.         associatesPoolQuery = GetEntityQuery(ComponentType.ReadOnly<MafiaStatusComponent>(), ComponentType.ReadOnly<MafiaTypeComponent>());
    50.         associatesPoolQuery.SetSharedComponentFilter(new MafiaStatusComponent { Status = AgentMafiaStatus.Pool }, new MafiaTypeComponent { Type = AgentMafiaType.Associate });
    51.  
    52.         soldiersPoolQuery = GetEntityQuery(ComponentType.ReadOnly<MafiaStatusComponent>(), ComponentType.ReadOnly<MafiaTypeComponent>());
    53.         soldiersPoolQuery.SetSharedComponentFilter(new MafiaStatusComponent { Status = AgentMafiaStatus.Pool }, new MafiaTypeComponent { Type = AgentMafiaType.Soldier });
    54.     }
    55. }
     
  2. jlzuri

    jlzuri

    Joined:
    Oct 12, 2015
    Posts:
    1
    Hello Charles,

    I landed on this page looking for an example of what Unity's documentation meant by this: "filter settings are not considered when caching queries". I guess we both have now the answer, although I hope you did not have two wait for two years to get yours.
     
    charleshendry likes this.
  3. charleshendry

    charleshendry

    Joined:
    Jan 7, 2018
    Posts:
    98
    Thanks for following up! I hadn't picked up on that note in the documentation. I will have ended up rewriting that part of the code.