I’m trying to make an enemy wait for the player to do something, then after 2 seconds attack the player and wait for player input again.
Here’s the code so far:
void Update() {
if (playerTurn == false) StartCoroutine(CycleEnemies());
}
public void Attack() {
if (playerTurn == true) enemies[0].GetComponent<EnemyStats>().enemyHealth -= playerStatsHandler.attack;
playerTurn = false;
}
IEnumerator CycleEnemies() {
foreach (GameObject enemy in enemies) {
yield return new WaitForSeconds(2);
playerStatsHandler.TakeDamage(enemy.GetComponent<EnemyStats>().enemyAttack);
if (System.Array.IndexOf(enemies, enemy) == enemies.Length - 1) {
playerTurn = true;
}
}
}
The player presses a UI button which triggers “Attack”, which then sets “playerTurn” to false, allowing “CycleEnemies” to run.
What should happen is each enemy (currently only have one for simplicity) waits 2 seconds and attacks the player, if the enemy is the last in the array of enemies, it will set “playerTurn” to true, not letting the method run again on its own, and waiting for the player to press the button again.
What happens instead, is the enemy waits 2 seconds, then every frame takes the player’s health down forever.
I did google multiple things, like “WaitForSeconds only running once”, everything I found hasn’t worked so far.
This is the only thing in “TakeDamage”: health -= damage;
Did you check that the boolean is being set to false constantly? How are you using the attack function? There’s clearly something being triggered each frame in the update somehow if it’s just being spammed. I think also you might be playing the coroutine each frame which might be why you’re having problems too but I’ll need to double check that, you just want it to happen once.
Added a second bool “enemyAttacking”, checked for it along with “playerTurn”, and set it to true at the start of the coroutine and back to false at the end. Seems to be working fine now.
Update is called every frame, so you’re invoking CycleEnemies again every frame when playerTurn is false. What you need to do is to only invoke CycleEnemies once in your update loop, then wait until it has finished.
One way to achieve this is to use a coroutine instead of the Update function.