- Home /
Can I call multiple functions from other scripts in a foreach loop?,Can I call multiple functions in a foreach loop?
Hi there,
I am trying to detect and damage enemies in an array of layers (enemyLayers) with a foreach loop by calling "takedamage" functions from other scripts, but so far I've been only able to damage only one of the enemies. So the first line in the foreach loop is working; enemy.GetComponent().TakeDamage(attack1Damage);
but the second one is not working; enemy.GetComponent().TakeDamageBanditBowman(attack1Damage);
I've been trying to solve this problem since yesterday and I did a lot of research on this but couldn't find a solution to my problem, so I am open to all possible solutions. Thanks.
private IEnumerator attack1DamageEnemies()
{
//Detect enemies in range of attack
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange,enemyLayers);
yield return new WaitForSeconds(waitToDamageEnemiesA1);
//Damage enemies
foreach (Collider2D enemy in hitEnemies)
{
enemy.GetComponent<BanditMeleeController>().TakeDamage(attack1Damage);
enemy.GetComponent<BanditBowmanController>().TakeDamageBanditBowman(attack1Damage);
}
}
Do you have Bandit$$anonymous$$eleeController and BanditBowmanController components in Every enemy in the loop? Otherwise there would be exceptions. Do you see any exceptions in the console?
No I don't and that is the main problem, these two are different enemies (Bandit $$anonymous$$elee and Bandit Bowman) so they have different kinds of AI and I didn't want to put all of those scripts to every individual enemy. Also I have some animation going on with them, so I didn't want to create a single script for them to takedamage because I don't know how can I handle the animations that way. Really confused...
Answer by ShadyProductions · Mar 19, 2020 at 01:43 PM
What you need to do is use inheritance and use override methods.
// This class serves as your base class, and should not be added to any enemy gameobject
public abstract class Enemy : MonoBehaviour
{
public virtual void TakeDamage(int damage)
{
// Base damage dealing
}
}
// Put this script on your enemy gameobject
public class BanditMelee : Enemy
{
public override void TakeDamage(int damage)
{
// Some other way of taking damage
}
}
// Put this script on your enemy gameobject
public class BanditBowman : Enemy
{
public override void TakeDamage(int damage)
{
// Some other way of taking damage
}
}
// The GetComponent<Enemy>() will still return the correct instance.
// (either BanditMelee or BanditBowman but as it's base class Enemy)
foreach (Collider2D enemy in hitEnemies)
{
enemy.GetComponent<Enemy>().TakeDamage(attack1Damage);
}
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/inheritance
One quick question, in my base class should I create all the variables and methods from nothing again? Or should I simply call the functions that I've created to damage enemies? By the way here is one example of take damage function;
public void TakeDamage(int damage)
{
if (invincibleCounter <= 0 && currentHealth > 0)
{
currentHealth -= damage;
//Play Hurt Animation
KnockBack();
if (currentHealth <= 0)
{
Die();
}
else
{
invincibleCounter = invincibleLength;
}
}
}
Your base class is the base of all enemies, it will be shared between them. So there you will have all your base functionality like health, shield, damage methods etc.
Then in your subclasses you can choose to override some methods, if you need different logic for that specific subclass.
I can't thank you enough... I've been trying to work this out since yesterday but couldn't managed it and now it all works perfectly and so glad that I've learnt about "inheritance" and "override", thanks again :)