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 Check if entity has aspect

Discussion in 'Entity Component System' started by ComradeVanti, Apr 30, 2023.

  1. ComradeVanti

    ComradeVanti

    Joined:
    May 22, 2015
    Posts:
    25
    How do I check if an entity I already have a reference to has a given aspect? There are equivalents for components such as
    SystemApi.HasComponent
    but there is no
    HasAspect
    or
    TryAspect
    .

    Seems like the API is not here yet. Any workarounds?
     
  2. ComradeVanti

    ComradeVanti

    Joined:
    May 22, 2015
    Posts:
    25
    Only way I can think of is to just try-catch the aspect creation, but that seems weak
     
  3. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Check against queries. If there's a match - there's an aspect.
     
  4. ComradeVanti

    ComradeVanti

    Joined:
    May 22, 2015
    Posts:
    25
    @xVergilx as I said, I already have a reference to the entity from previous transformations. In this case, one of my entities has a buffer of entities it can see. Now I want to check which of these entities are "Food" by checking whether they have the "Food-aspect". So basically I have a
    Entity[]
    and want to foreach where
    FoodAspect
    .
     
    Last edited: May 2, 2023
  5. ComradeVanti

    ComradeVanti

    Joined:
    May 22, 2015
    Posts:
    25
  6. ComradeVanti

    ComradeVanti

    Joined:
    May 22, 2015
    Posts:
    25
    I found a solution for now

    Code (CSharp):
    1. [BurstCompile]
    2. private static IEnumerable<ComponentType> RequiredComponents<T>(this IAspectCreate<T> create, bool isReadonly)
    3.   where T : IAspect
    4. {
    5.   var list = new UnsafeList<ComponentType>(10, Allocator.Temp);
    6.   create.AddComponentRequirementsTo(ref list, isReadonly);
    7.  
    8.   foreach (var type in list)
    9.   {
    10.     yield return type;
    11.   }
    12.  
    13.   list.Dispose();
    14. }
    15.  
    16. [BurstCompile]
    17. public static bool TryAspect<TAspect>(this EntityManager entityManager, Entity entity, bool isReadonly, out TAspect aspect)
    18.   where TAspect : unmanaged, IAspect, IAspectCreate<TAspect>
    19. {
    20.   var create = new TAspect();
    21.  
    22.   foreach (var component in create.RequiredComponents(isReadonly))
    23.   {
    24.     if (entityManager.HasComponent(entity, component)) continue;
    25.     aspect = default;
    26.     return false;
    27.   }
    28.  
    29.   aspect = entityManager.GetAspect<TAspect>(entity);
    30.   return true;
    31. }
     
    Last edited: May 2, 2023
    xVergilx and FaithlessOne like this.
  7. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Another option is to prefilter (or filter later) outputs of the system - ensure required components exist for the data in the stored buffer. This way you can do this in a separate job without stalling the main thread. Use ComponentLookup / BufferLookup to perform checks and remove no longer valid data.