Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Use OverlapSphere to count ?

Discussion in 'Scripting' started by Quast, Jan 2, 2019.

  1. Quast

    Quast

    Joined:
    Jul 5, 2015
    Posts:
    560
    I'm trying to count number of enemies around object. I know my mistake is with "hitColliders" in "for" function. I did this to pass stupid error. Now, could any one please help me with this ?

    Code (CSharp):
    1.  
    2. public int enemies;
    3.  
    4. void Update()
    5. {
    6.  
    7. Collider[] hitColliders = Physics.OverlapSphere(gameObject.transform.position, 2);
    8. foreach (Collider hitCol in hitColliders)
    9. {
    10. if (hitCol.tag == ("enemy"))
    11. {
    12.  
    13. for (int i = 0; i <= hitColliders.Length; i++)
    14. {
    15. if (hitColliders[i].gameObject.transform.tag == "enemy")
    16. {
    17. enemies = i;
    18. }
    19. }
    20. }
    21.  
    22. }
    23.  
    24. }
    25.  
    26.  
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,513
    Code (csharp):
    1.  
    2. public class EnemyTracker
    3. {
    4.  
    5.     public int enemies;
    6.  
    7.     //try making your values configurable for customization
    8.     public float radius = 2f;
    9.     public LayerMask mask = -1; //default to all layers
    10.  
    11.     void Update()
    12.     {
    13.         //you may want to consider not calling this every single frame, but instead only when the value is needed
    14.         this.enemies = this.CountNearEnemies();
    15.     }
    16.  
    17.     private int CountNearEnemies()
    18.     {
    19.         //I would consider changing this to OverlapSphereNonAlloc to reduce gc stutter
    20.         var hits = Physics.OverlapSphere(this.transform.position, radius, mask); //use those customizable variables instead
    21.         int cnt = 0;
    22.    
    23.         //one fatal flaw here is that if the enemy consists of more than 1 collider tagged 'enemy', it'll count multiple times.
    24.         //you may want to consider some method of relating an enemy all together as a single entity.
    25.         foreach(var c in hits)
    26.         {
    27.             if(c.CompareTag("enemy")) //use CompareTag, not tag ==
    28.             {
    29.                 cnt++;
    30.             }
    31.         }
    32.    
    33.         return cnt;
    34.     }
    35.  
    36. }
    37.  
     
    Last edited: Jan 2, 2019
    Quast likes this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    You are iterating the returned colliders once from line 8, with your foreach(), and then each time through you are iterating all the list again from line 13, your for() loop.

    In all cases, if it finds an enemy, it sets enemies equal to the index of the last one that was an enemy. With one enemy in your sphere he will be at i == 0 so your enemies will be equal to zero. I'm guessing that is not what you want.

    Instead you want to do this:

    1. make a blank list of colliders for the enemies:

    Code (csharp):
    1. List<Collider> Enemies = new List<Collider>();
    2. inside your loop (you only need the outer foreach loop!), and inside of your "if tag is enemy" block, do this:

    Code (csharp):
    1. Enemies.Add( hitCol);
    3. Close the loop immediately after that.

    At the end of the loop, to see how many enemies were found this frame:

    Code (csharp):
    1. Debug.Log( "enemies found: " + Enemies.Count);
    And then you can study the list of enemies and you have each of their colliders, from which you can get their gameObjects, transforms, etc.

    Does that make sense for what you're trying to do?
     
    Quast likes this.