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 Can/should you query Entities by index range?

Discussion in 'Entity Component System' started by Tudor, Feb 27, 2023.

  1. Tudor

    Tudor

    Joined:
    Sep 27, 2012
    Posts:
    150
    I know you should avoid cache misses. E.g. accessing random entities en masse is bad.
    I know you're supposed to query entities by using "Tags".
    I also know "The entity and component arrays returned by a EntityQuery are guaranteed to be "parallel", that is, the same index value always applies to the same entity in any array."

    But here's a common scenario:

    - I have a game with 100,000 entities (let's say they're bullets)
    - They're all pooled (ie created in the beginning of the game, in sequence)
    - I know every 10,000 entities belongs to one player.
    How do I tell Player 7's system, to loop through their 10,000 entities?

    I would want to say "EntityManager, please fetch me entities typeof(BulletTag), between index 60,000 and 70,000". Do I just fetch -all- BulletTag and for-loop starting at i=60,000? Is that right/efficient?

    Or am I wrong in wanting to iterate through sections of fixed entity pools? Many games were/are built like this afaik.
     
    Last edited: Feb 27, 2023
  2. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    228
    This sounds like a prime use case for shared components. You make an OwnedByPlayer shared component, and all the bullets have one, and it has a value on it (like an int) indicating which player it is. Then you can query by shared component value, and have one query per player that you can use to talk about all the entities for that player via WithSharedComponentFilter or similar.

    Under the hood, the entity data will all be grouped by shared component value, so if you process each player's bullets together, you won't have any extra cache misses.

    (Just don't get tempted to change the owner of a ton of bullets at once, because it has to re-group all the ones that change shared component value.)
     
    Tudor likes this.
  3. Tudor

    Tudor

    Joined:
    Sep 27, 2012
    Posts:
    150
    Aaah, so "ISharedComponent" triggers some sort of internal database sorting / id'ing. I thought it just slowly goes through all entities and checks the value...
    Great! Thanks.
     
    elliotc-unity likes this.