- Home /
Advanced Wave Spawner (Spawn Waves in random order)
Hi, the point of what I want to do is aleready indicated in the title. I have an array of waves set that are spawned in a numerical order one by one. I want the waves to be selected and spawned randomly, and for example if there was selected wave number 2 it could only be selected again after all other waves have passed. Here's my WaveSpawner code:
public class WaveSpawner : MonoBehaviour
{
public enum SpawnState {SPAWNING, WAITING, COUNTING};
[System.Serializable]
public class Wave
{
public string name;
public Transform[] enemy;
public int count;
public float rate;
}
public Wave[] waves;
private int nextWave = 0;
public float timeBetweenWaves = 5f;
private float waveCountdown;
private SpawnState state = SpawnState.COUNTING;
private float searchCountdown = 1f;
public Transform[] spawnPoints;
private int index;
void Start()
{
waveCountdown = timeBetweenWaves;
}
void Update()
{
if(state == SpawnState.WAITING)
{
if(!EnemyIsAlive())
{
WaveCompleted();
}
else
{
return;
}
}
if(waveCountdown <= 0)
{
if (state != SpawnState.SPAWNING)
{
StartCoroutine(SpawnWave(waves[nextWave]));
}
}
else
{
waveCountdown -= Time.deltaTime;
}
}
void WaveCompleted()
{
Debug.Log("Wave Completed");
state = SpawnState.COUNTING;
waveCountdown = timeBetweenWaves;
if(nextWave + 1 > waves.Length -1)
{
nextWave = 0;
Debug.Log("Completed all waves! Looping");
} else {
nextWave++;
}
}
bool EnemyIsAlive()
{
searchCountdown -= Time.deltaTime;
if(searchCountdown <= 0f)
{
searchCountdown = 1f;
if(GameObject.FindGameObjectsWithTag("Enemy") == null)
{
return false;
}
}
return true;
}
IEnumerator SpawnWave (Wave _wave) //want to wate a certain amount of seconds in metod
{
state = SpawnState.SPAWNING;
for(int i=0;i< _wave.enemy.Length; i++)
{
index = (index >= _wave.enemy.Length-1) ? 0 : index+1;
SpawnEnemy(_wave.enemy[index]);
yield return new WaitForSeconds(1f/_wave.rate);
}
state = SpawnState.WAITING;
yield break;
}
void SpawnEnemy (Transform _enemy)
{
Transform _sp = spawnPoints[ Random.Range (0, spawnPoints.Length)];
//SpawnEnemy
switch (_enemy.name)
{
case "BG3" :
_sp = spawnPoints[1];
break;
case "Notebook":
_sp = spawnPoints[2];
break;
}
Debug.Log("Spawning Enemy" +_enemy.name);
Instantiate (_enemy, _sp.position, _sp.rotation);
}
}
The variable nextWave in the WaveCompleted() method is responsible for the order of the waves. Thanks in advance for any help!
Answer by Aviryx · Aug 18, 2020 at 06:20 PM
What you need to do (imo) is to create a separate list to store how many waves there are and then pick from that. When a wave is selected it can be removed from the list until nothing is left.
1) create a list that will be used to count "how many and which waves are left to be spawned".
public List<Wave> waveTracker = new List<Wave>();
2) before spawning the "first" wave, add all of the waves to a list.
foreach (Wave individualWave in waves)
{
waveTracker.Add(individualWave);
}
3) Time to pick which (random) wave to spawn!
var randomSelection = Random.Range(0, waveTracker.Count);
4) Now you have the wave that needs to be spawned, you can remove that wave from the list.
waveTracker.Remove(randomSelection);
5) and spawn the selected (random) wave.
waves[randomSelection];
When you add all of the waves that have not been spawned to the list, you need to check if the result is higher than 0.... if it is then you have waves left to spawn. If the list is empty (because all waves have been spawned) then you need to repopulate the list and start again.
Hopefully this helps as it was all written off the top of my head.
Your answer
Follow this Question
Related Questions
whats the best way to randomize prefab faces and its facial expressions? 0 Answers
i want to spawn randomly 1 Answer
How can I create a script to create and then randomly select 1 of 3 spawning points? 1 Answer
How to generate random objects? 1 Answer
Simple random spawning system for 10 items without duplicates 2 Answers