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

How to compare two groups in a job?

Discussion in 'Entity Component System' started by BanJaxe, Nov 23, 2018.

  1. BanJaxe

    BanJaxe

    Joined:
    Nov 20, 2017
    Posts:
    47
    For example in a tower defense game you would need to iterate over each tower, and then for each tower iterate over all enemies in a radius and then select the closest to target.

    Code (CSharp):
    1.     struct TowerTargetJob : IJobProcessComponentData<Tower, Position>
    2.     {
    3.         public void Execute(ref Tower tower, ref Position position)
    4.         {
    5.            // Iterate over all Enemy Position components and find nearest
    6.            // tower.Target = nearest enemey entity
    7.         }
    8.     }

    When using component groups you can just do this:

    Code (CSharp):
    1.  
    2.     for (int i = 0; i < towerGroup.Length; i++)
    3.     {
    4.         for (int j = 0; j < enemyGroup.Length; j++)
    5.         {
    6.             // compare towerPositions[i] and enemyPositions[j]
    7.         }
    8.     }
     
  2. rjohnson06

    rjohnson06

    Joined:
    May 27, 2017
    Posts:
    17
    You can add a public field to your IJobProcessComponentDatab job and pass in the enemy group as chunks and iterate over those using chunk iteration. You may want to think about adding a spatial data structure that holds the enemies so you can quickly grab all enemies that are within a tower's range, rather than iterating over all enemies for each tower.
     
  3. BanJaxe

    BanJaxe

    Joined:
    Nov 20, 2017
    Posts:
    47
    I was looking at chunk iteration but it seemed like overkill, adds a lot of extra lines and complexity for something that can be done in two nested for loops using component groups.
     
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,655
    Best performance is overkill? Two nested loops it's slowest and poor approach. If you want performant code, you must follow strict rules. And chunk iteration or just IJobParallelFor\IJobProcessComponentData\IJobProcessComponentDataWithEntity this is not a big difference in the code, besides we do not forget that this is a multi-threaded code of just a couple of lines of Karl! ;)
    818343149_4347189.jpg
     
    Lurking-Ninja likes this.
  5. BanJaxe

    BanJaxe

    Joined:
    Nov 20, 2017
    Posts:
    47
    I got chunk iteration working: https://pastebin.com/K2kP9dV0

    Not sure I did it optimally but it works at least.

    One thing I noticed when profiling is the job only ever runs on the main thread or a single worker thread. Is that because the number of towers is low (<100) compared to the number of enemies (up to 5k) so it doesn't split the work up over multiple threads?
     
    Last edited: Nov 27, 2018
  6. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    here someone asked exactly this question at unite LA
     
    e199 likes this.
  7. BanJaxe

    BanJaxe

    Joined:
    Nov 20, 2017
    Posts:
    47
    Thanks