Search Unity

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,685
    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