Its a 2d Platformer. When my player attacks the enemy it register all gameobjects within a circle (hitEnemies) that are on layer “enemy”. My problem is that my enemies have different scritps since they are using different movement/ attack logic etc. But all enemies naturally have a "takeDamage " function.
My problem is that if i do two (or more) calls in the **for each-**loop, the only one that works is the top one.
I tryed to solve this by following code but it works only for enemy1 and enemy2. If i create a prefab of enemy1 which would be enemy1(1) it doesnt work which makes sense since im looking for particular name.
Both of these will be called and we don’t know what “works” and “not works” means. Don’t worry that somehow there’s some magical limit on how many things you can call in a specific C# construct. It sounds like you’re having a debugging problem and/or something else is going on. What that is, is impossible to tell.
It’s not clear why you have an “enemy1script” and an “enemy2script” on each GameObject that you’re detecting colliders on but that’s all the above is doing. It’s not two separate enemy GameObjects or anything. The second approach checks the GameObject name and calls each script appropriately yet you say it “doesn’t work”. You’re doing something else wrong here that isn’t clarified by the script you’re presenting unfortunately. If one enemy has one type of script and another has a different script then the second approach “works”.
Warning! This is not a tutorial, following code is written in the comment field without testing with a compiler, might contain minor syntax errors.
interface IDamagable {
void TakeDamage(int damage);
}
class Enemy1 : MonoBehavior, IDamagable {
public void TakeDamage(int damage) {
// implement for enemy 1
}
}
class Enemy2 : MonoBehavior, IDamagable {
public void TakeDamage(int damage) {
// implement for enemy 2
}
}
// in the place where you want to do damage:
enemy.GetComponent<IDamagable>().TakeDamage(10);
Different approach is to use composition. Separate health and taking damage into a component which is independent from rest of enemy logic. That way enemy1 will have two components attached (in addition to all the components for visual and physics stuff): Enemey1, Health and enemy2 will have Enemy2 and Health components. Optionally you can add an event which gets sent when Health component is damaged, that way you can also have some enemy specific reaction to damage.
class Health : MonoBehavior
{
pubic UnityEvent OnDamge = new UnityEvent();
public int health;
public void TakeDamge(int damage) {
health -= damage;
OnDamage.Invoke();
if (health <= 0) {
// implement death
}
}
}
class Enemy1 : MonoBehavior {
void Start() {
// Note this is optional, you don't need to do this if there is no enemy specific logic when taking damage
GetComponent<Health>().OnDamage.AddListener(DamageTaken);
}
void DamageTaken() {
// play damage taken animation
// spawn blood particles
}
}
// In the place doing damage:
enemy.GetComponent<Health>().TakeDamage(10);
Thanks for advice with code tag. What i meant is that i have a player - the script i posted belongs to the player. Player has a list where he register all of the enemies that it hit. At the moment, i have created two different enemies with two different scripts that both have takeDamage function - which substracting the hp from the enemy.
The second approach dont work because if im creating a prefab of for instance enemy1 the name if that prefab will be enemy1(1), enemy1(2) etc and so the code only works for enemy1. My question was of there is some “nice” way to use functions in for each loop so that it calls it for all enemies that are hitted.