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

Test Existence of Component when using EntityQueryDesc.Any

Discussion in 'Entity Component System' started by PublicEnumE, Aug 25, 2019.

  1. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    I'm writing a job which tests to see if an entity has one of two components. It then behaves slightly differently depending on which one is present.

    Below, every entity has a FooComponent. Half of them have a BarComponent, and half have a BazComponent.

    Is there any way to test for the existence of a Bar or Baz component from inside the job, without passing in an ComponentDataFromEntity<T>? For some readon that feels like it might be overkill. Please let me know if I'm wrong about that.

    Code (CSharp):
    1. public class TestSystem : JobComponentSystem
    2. {
    3.     EntityQuery fooQuery;
    4.  
    5.     protected override void OnCreate()
    6.     {
    7.         EntityQueryDesc fooQueryDesc = new EntityQueryDesc
    8.         {
    9.             All = new ComponentType[] { ComponentType.ReadWrite<FooComponent>() },
    10.             Any = new ComponentType[] { ComponentType.ReadWrite<BarComponent>(), ComponentType.ReadWrite<BazComponent>() }
    11.         };
    12.  
    13.         fooQuery = GetEntityQuery(fooQueryDesc);
    14.  
    15.         RequireForUpdate(fooQuery);
    16.     }
    17.  
    18.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    19.     {
    20.         return new Job().Schedule(fooQuery, inputDeps);
    21.  
    22.     }
    23.  
    24.     private struct Job : IJobForEach_C<FooComponent>
    25.     {
    26.         public void Execute(FooComponent fooComponent)
    27.         {
    28.             // check for existence of Bar of Baz?
    29.         }
    30.     }
    31. }
     
    Last edited: Aug 25, 2019
  2. desertGhost_

    desertGhost_

    Joined:
    Apr 12, 2018
    Posts:
    259
    I'm not sure if you can do that, but I've been handling this in a slightly different way. I've been creating multiple jobs with RequireComponentTag / ExcludeComponent attributes.

    Code (CSharp):
    1.  
    2. protected override JobHandle OnUpdate(JobHandle inputDeps)
    3. {
    4.     return new BazJob().Schedule(this, new BarJob().Schedule(this, inputDeps));
    5. }
    6.  
    7. [RequireComponentTag(typeof(Bar))]
    8. [ExcludeComponent(typeof(Baz))]
    9. private struct BarJob : IJobForEach_C<FooComponent>
    10. {
    11.     public void Execute(FooComponent fooComponent)
    12.     {
    13.     }
    14. }
    15.  
    16. [RequireComponentTag(typeof(Baz))]
    17. [ExcludeComponent(typeof(Bar))]
    18. private struct BazJob : IJobForEach_C<FooComponent>
    19. {
    20.     public void Execute(FooComponent fooComponent)
    21.     {
    22.     }
    23. }
    That way each job only processes entities that have the desired component. If you want to share code between your jobs you can use a static function.
     
    PublicEnumE likes this.
  3. Enzi

    Enzi

    Joined:
    Jan 28, 2013
    Posts:
    954
    You can use ComponentDataFromEntity<T> in jobs and check with Exists(entity).
    2 jobs also work of course, might be faster and cleaner.