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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Question Use the WithAny component match to query for another entity

Discussion in 'Entity Component System' started by Keendra, Dec 31, 2020.

  1. Keendra

    Keendra

    Joined:
    Jul 14, 2014
    Posts:
    3
    I currently have a ”workaround” in my project I would be thrilled to be rid of. Basically, there are two different entities with different components that both have one component in common, ComponentX. ComponentX holds an enum that can be TypeA, TypeB, TypeC and TypeD. At some points, Entity X needs to add to a variable in a component in Entity Y with the same type set in ComponentX. So I have an Entities.ForEach that grab the right EntityX, get the type, and loop through a list of Entity Ys until I find the entity with the matching type. Not very sophisticated.

    What I want, and think would be a more dots:y approach, would be to get rid of ComponentX and instead have ComponentA, B, C and D. I’m running into a few problems with this approach though, unless I create duplicate code for each of these types.. Which obviously I don’t want. I need something along the lines of:

    Code (CSharp):
    1. Entities
    2.       .WithAll<ComponentI, ComponentJ, Selected>()
    3.       .WithAny<ComponentA, ComponentB, ComponentC, ComponentD>()
    4.       .ForEach((Entity entity) =>
    5.       {
    6.         // Here I want to know which ComponentA-D
    7.         // So I can use it and query for EntityY with the same component
    8.       })
    1. WithAny only supports three options, which makes me think this isn’t how they want me to achieve my goal.
    2. Is there a nice way to know which component triggered a match and use it to query for EntityY (hence, not HasComponent-GetComponent which becomes messy).
    In my project I currently have 9 different types (and more will be added), so ideally it would be best if it was possible to assign them to a group (like with WriteGroups), and have access to the component that was part of the group in the .ForEach..?
     
  2. Timboc

    Timboc

    Joined:
    Jun 22, 2015
    Posts:
    234
    If I understand correctly, this is basically the main reason to still use IJobChunk imo - so you know what Components are present for the chunk you are currently iterating. There has been talk of Chunk ForEach lambda but that seems unlikely atm. If it's not performance critical If(HasComponent<ComponentA>(entity))... does work quite well. If it is, IJobChunk. What also works well to reduce duplicate code is to move some logic out into static methods invoked within the lambdas.
     
    Keendra likes this.
  3. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,986
    So does WithAll(). They are just wrappers over three calls with a single type each. You can have multiple WithAny calls and they combine into one single "Any" group.

    This is IJobChunk territory.
     
    Keendra likes this.
  4. Keendra

    Keendra

    Joined:
    Jul 14, 2014
    Posts:
    3
    Thanks for the confirmation, I will use IJobChunk for this.