2
\$\begingroup\$

I am having a problem with a foreach loop. When my AOE ability hits an enemy it creates a CircleCollider2D and puts all the enemies on a list, which then the loop goes through and adds damage to their scripts.

private void OnTriggerEnter2D(Collider2D other)
{
    if(other.tag == "Enemy")
    {
        targets.Add(other);

        foreach (Collider2D enemy in targets)
        {
            EnemyHealth hp = enemy.GetComponentInChildren<EnemyHealth>();

            hp.TakeDamage(abilityConfig.baseDamage);

            print(enemy.name + " takes " + abilityConfig.baseDamage + "damage!");
        }
    }        
}

But as you can see from the picture below the loop goes 3 times over one enemy, 2 times over the second one and once over the third. Unity console output

As these enemies are the same type they all have the same EnemyHealth script. If anyone would point me in the right direction I would greatly appreciate it.

\$\endgroup\$
  • \$\begingroup\$ How many enemies do you have in total, also you are not checking if the enemy you hit is already in the list or not, lastly please elaborate more on what you are trying to achieve, I mean you want to apply damage to all your enemies if it hits any one of them??? \$\endgroup\$ – Digvijaysinh Gohil Apr 25 '19 at 6:05
  • \$\begingroup\$ Hi, I am trying to create an AOE spell that damages every enemy in a certain area, no matter how many there are they would all receive the same amount of damage. \$\endgroup\$ – madeer Apr 25 '19 at 6:20
  • \$\begingroup\$ It looks like it might be because when it visits the first enemy, there's only one entry in targets - itself. \$\endgroup\$ – Polar May 8 '19 at 11:21
4
\$\begingroup\$

OnCollisionEnter executes for each entity that collided. So you don't need foreach loop at all.

private void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "Enemy")
    {
        EnemyHealth hp = enemy.GetComponentInChildren<EnemyHealth>();
        hp.TakeDamage(abilityConfig.baseDamage);
        print(enemy.name + " takes " + abilityConfig.baseDamage + " damage!");
    }
}
\$\endgroup\$
  • \$\begingroup\$ This fixed it. Now i see why it was doing...what it was doing. Thank you. \$\endgroup\$ – madeer Apr 25 '19 at 6:45
0
\$\begingroup\$

In response to your comment, if you want to hit every enemy than i suggest you get all the reference of your enemies and then apply the damage like following

private void OnTriggerEnter2D(Collider2D other)
{
    if(other.tag == "Enemy")
    {
        // Change targets type to List<GameObjects>
        targets.Clear();
        targets.AddRange(GameObject.FindGameObjectsWithTag("Enemy"));

        foreach (GameObject enemy in targets)
        {
            EnemyHealth hp = enemy.GetComponentInChildren<EnemyHealth>();

            hp.TakeDamage(abilityConfig.baseDamage);

            print(enemy.name + " takes " + abilityConfig.baseDamage + " damage!");
        }
    }        
}  

We are here basically checking if we hit any enemy, if thats the case we are first clear the list then add all the enemies to the list, so no duplicates there,

Then we are looping through all pretty much the same

\$\endgroup\$
  • 1
    \$\begingroup\$ Thank you for your help too, i have added a check for duplicates as well. \$\endgroup\$ – madeer Apr 25 '19 at 6:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.