- Home /
Wave Spawner not working |Does not detect if an object is destroyed
Hey, I have a question regarding this script. I have watched this tutorial several times but I can't detect the error. Can someone help me? The script is spawning 2 Enemies like i said it should do, but its not detecting if delete these Enemies. I appreciate any answer. Thanks in advance! Finn Part 1 https://www.youtube.com/watch?v=Vrld13ypX_I Part 2 https://www.youtube.com/watch?v=q0SBfDFn2Bs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WaveSpawner : MonoBehaviour {
public enum SpawnState { Spawning, Waiting, Counting } // state of the Wave
[System.Serializable]
public class Wave
{
public string name; //wave name: Easy
public Transform enemy; //Which Prefab should be spawned: Enemy
public int count; //how much Enemys should be spawned per wave: 6
public float rate; //how often the count of enemies should spawn
}
public Wave[] waves;
private int nextWave = 0;
public float timeBetweenWaves = 5f; //Time between waves: 5f = 5seconds
public float waveCountdown; //time Counting down to next wave: 3... 2... 1...
private float searchCountdown = 1f; // how long to search for alive enemies
private SpawnState state = SpawnState.Counting;
void Start()
{
waveCountdown = timeBetweenWaves;
}
void Update()
{
if (state == SpawnState.Waiting) //starts method to check if enemies are still alive
{
searchCountdown = 1f; //search countdown 1s
if (!EnemyIsAlive())
{
//begin a new Wave
Debug.Log("Wave Completed!");
return;
}
else
{
return;
}
}
if (waveCountdown <= 0) //ask if ready for new Wave
{
if (state != SpawnState.Spawning) //ask if Waves are already spawning
{
StartCoroutine( SpawnWave ( waves[nextWave] ) ); //start Spawning Routine
}
}
else
{
waveCountdown -= Time.deltaTime; //if not count down
}
}
bool EnemyIsAlive() //method to search for living enemies
{
searchCountdown -= Time.deltaTime; //count down search time
if (searchCountdown <= 0f) //if search countdown = 0
{
if (GameObject.FindGameObjectWithTag("Enemy") == null) //check if enemy is alive
{
return false; //enemies arent allive
}
}
return true; // enemies are allive
}
IEnumerator SpawnWave (Wave _wave) //Spawning Routine
{
Debug.Log("Spawning Wave: " + _wave.name);
state = SpawnState.Spawning; //State: Spawning
for (int i = 0; i < _wave.count; i++) //loop through amount of enemy
{
SpawnEnemy(_wave.enemy); //spawn enemy Method
yield return new WaitForSeconds(1f / _wave.rate); //time between spawning of each enemy
}
state = SpawnState.Waiting; //State: Waiting
yield break; //stop
}
void SpawnEnemy (Transform _enemy) //spawn enemy Method
{
Debug.Log("Spawning Enemy: " + _enemy.name);
Instantiate(_enemy, transform.position, transform.rotation);
}
}
Answer by Developers_Hub · Jan 16 at 11:20 AM
I think EnemyIsAlive() is returning the wrong value, I've made some changes and adjustments, hope it helps.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class WaveSpawner: MonoBehaviour
{
public enum SpawnState { Spawning, Waiting, Counting, Finished } // State of the wave
[System.Serializable] public class Wave
{
public string name = "Easy"; // Wave name: Easy
public Transform enemy = null; // Which prefab should be spawned: Enemy
public int count = 6; // How much enemys should be spawned per wave: 6
public float rate = 3; // How often the count of enemies should spawn
}
public Wave[] waves = null;
public float timeBetweenWaves = 5f; // Time between waves: 5f = 5 seconds
public int countdownFrom = 3; // The number which countdown starts from
public int waveCountdown = 0; // Time Counting down to next wave: 3... 2... 1...
private int waveIndex = 0;
private int enemyIndex = 0;
private float timer = 0;
private SpawnState state = SpawnState.Counting;
private string enemyTag = "Enemy";
private void Start()
{
waveIndex = 0;
enemyIndex = 0;
state = SpawnState.Waiting;
waveCountdown = 0;
timer = 0;
if(waves == null || waves.Length == 0)
{
state = SpawnState.Finished;
}
}
void Update()
{
if(state == SpawnState.Finished)
{
return;
}
switch (state)
{
case SpawnState.Spawning:
if(enemyIndex >= waves[waveIndex].count)
{
enemyIndex = 0;
waveIndex++;
state = SpawnState.Waiting;
Debug.Log("Wave spawned.");
if (waveIndex < waves.Length)
{
Debug.Log("Waiting for the next wave.");
}
else
{
Debug.Log("That was the last wave.");
}
}
else
{
if(timer >= waves[waveIndex].rate)
{
timer = 0;
waveCountdown = countdownFrom;
enemyIndex++;
SpawnEnemy(waves[waveIndex].enemy);
}
else
{
timer += Time.deltaTime;
}
}
break;
case SpawnState.Waiting:
if (waveIndex >= waves.Length)
{
if (!EnemyIsAlive())
{
state = SpawnState.Finished;
Debug.Log("All Waves Completed. Level finished.");
}
}
else
{
if (timer >= timeBetweenWaves)
{
timer = 0;
waveCountdown = countdownFrom;
state = SpawnState.Counting;
Debug.Log("Countdown started.");
}
else
{
timer += Time.deltaTime;
}
}
break;
case SpawnState.Counting:
if (timer >= countdownFrom)
{
timer = 0;
waveCountdown = 0;
state = SpawnState.Spawning;
Debug.Log("Countdown finished. Spawning new wave.");
}
else
{
timer += Time.deltaTime;
waveCountdown = countdownFrom - Mathf.FloorToInt(timer);
}
break;
}
}
private bool EnemyIsAlive() // Method to search for living enemies
{
GameObject[] objects = GameObject.FindGameObjectsWithTag(enemyTag);
return objects != null && objects.Length > 0;
}
private void SpawnEnemy(Transform _enemy) // Spawn enemy Method
{
Transform enemy = Instantiate(_enemy, transform.position, transform.rotation);
enemy.tag = enemyTag;
Debug.Log("Enemy spawned: " + _enemy.name);
}
}
Hey, now the WaveCountdown starts. This is great! Unfortunately it starts again and again and not only when an object disappears, so that I have a bunch of enemies running around after a very short time. How could this be changed?
Change this and the next wave wont start until you remove all the enemies of the current wave.
case SpawnState.Spawning:
if (enemyIndex >= waves[waveIndex].count)
{
if (!EnemyIsAlive())
{
enemyIndex = 0;
waveIndex++;
state = SpawnState.Waiting;
if (waveIndex < waves.Length)
{
Debug.Log("Waiting for the next wave.");
}
else
{
Debug.Log("That was the last wave.");
}
}
}
else
{
if (timer >= waves[waveIndex].rate)
{
timer = 0;
waveCountdown = countdownFrom;
enemyIndex++;
SpawnEnemy(waves[waveIndex].enemy);
}
else
{
timer += Time.deltaTime;
}
}
break;