Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question IJobEntity seems to create an extra query compared to Entities.ForEach

Discussion in 'Entity Component System' started by bajankristof, Aug 12, 2022.

  1. bajankristof

    bajankristof

    Joined:
    Mar 4, 2017
    Posts:
    2
    I've been playing around with ECS for a bit now and it looks like using IJobEntity with EntityQuery creates an extra query compared to a properly setup Entites.ForEach.

    Here's what I mean:
    Code (CSharp):
    1. public partial class SystemA : SystemBase
    2. {
    3.     protected override void OnUpdate()
    4.     {
    5.         Entities
    6.             .WithAll<DungeonCard, StateLock>()
    7.             .WithNone<PlayerCardTag, EnemyCardTag>()
    8.             .ForEach((Entity entity, int entityInQueryIndex, ref StateLock stateLock) =>
    9.             {
    10.  
    11.             }).ScheduleParallel();
    12.     }
    13. }
    14.  
    15. public partial struct JobB : IJobEntity
    16. {
    17.     public void Execute(Entity entity, [EntityInQueryIndex] int entityInQueryIndex, ref StateLock stateLock)
    18.     {
    19.     }
    20. }
    21.  
    22. public partial class SystemB : SystemBase
    23. {
    24.     private EntityQuery dungeonQuery;
    25.     private EntityQuery enemySpawnQuery;
    26.  
    27.     protected override void OnCreate()
    28.     {
    29.         dungeonQuery = GetEntityQuery(ComponentType.ReadOnly<Dungeon>());
    30.         enemySpawnQuery = GetEntityQuery(
    31.             ComponentType.Exclude<PlayerCardTag>(),
    32.             ComponentType.Exclude<EnemyCardTag>(),
    33.             ComponentType.ReadOnly<DungeonCard>(),
    34.             ComponentType.ReadWrite<StateLock>()
    35.         );
    36.     }
    37.  
    38.     protected override void OnUpdate()
    39.     {
    40.         Dependency = new JobB{}.ScheduleParallel(enemySpawnQuery, Dependency);
    41.     }
    42. }
    When inspecting SystemA at runtime I can see that as expected, there's a single query:


    But when inspecting SystemB at runtime, there are not two queries (dungeonQuery and enemySpawnQuery), but instead three. There's an extra query with Read & Write access to Entity and StateLock which almost makes sense provided the signature of JobB only contains those:

    The problem with this is that this query keeps the system running even if the actual query attached to the job doesn't match a single entity in the scene.

    So question #1: I don't know whether this is intentional or not?
    And question #2: If it is intentional, how do I prevent that extra query from being created and keeping the system running unnecessarily?
     

    Attached Files:

  2. tassarho

    tassarho

    Joined:
    Aug 25, 2019
    Posts:
    64
    Did you try adding attribut [WithAll<>], [WithNone<>] to the IJobEntity?
     
    Anthiese and bajankristof like this.
  3. bajankristof

    bajankristof

    Joined:
    Mar 4, 2017
    Posts:
    2
    @tassarho that's exactly what I needed but didn't know existed, thanks a lot!