- Home /
How do I add multiple different enemies to a wave spawner?
Hi, I'm am trying to create a wave spawner that is editable in the editor. I am currently using a wave spawner from Brackey's tutorial. The spawner works great and all, however I can only have one type of enemy spawn per wave. I have seen countless questions liked this asked, (most answer with lists/arrays) but I'm struggling to implement those systems into the code. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
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 Transform[] spawnPoints;
public float timeBetweenWaves = 0f;
private float waveCountdown;
public float timeUnitlNextWave;
private float nextWaveCountdown;
public SpawnState state = SpawnState.COUNTING;
void Start()
{
if (spawnPoints.Length == 0)
{
Debug.LogError("No spawn points referenced.");
}
waveCountdown = timeBetweenWaves;
nextWaveCountdown = timeUnitlNextWave;
}
void Update()
{
if (state == SpawnState.WAITING)
{
timeUnitlNextWave -= Time.deltaTime;
if (timeUnitlNextWave <= 0)
{
WaveCompleted();
}
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;
timeUnitlNextWave = nextWaveCountdown;
if (nextWave + 1 > waves.Length - 1)
{
//Add win screen?
Debug.Log("Win!");
nextWave = 0;
this.GetComponent<WaveSpawner>().enabled = false;
}
else
{
nextWave++;
}
}
IEnumerator SpawnWave(Wave _wave)
{
Debug.Log("Spawning Wave: " + _wave.name);
state = SpawnState.SPAWNING;
for (int i = 0; i < _wave.count; i++)
{
SpawnEnemy(_wave.enemy);
yield return new WaitForSeconds(1f/_wave.rate);
}
state = SpawnState.WAITING;
yield break;
}
void SpawnEnemy(Transform _enemy)
{
Debug.Log("Spawning Enemy: " + _enemy.name);
Transform _sp = spawnPoints[Random.Range(0, spawnPoints.Length)];
Instantiate(_enemy, _sp.position, _sp.rotation);
}
}
Answer by Bunny83 · Jul 24, 2020 at 11:57 AM
We had a similar question a few times now. Back then I posted an example wave spawner template which is quite flexible (though of course it can't cover all cases). Each wave consists of an arbitrary number of wave actions. Each action can spawn a certain number of one prefab. The actions are carried out in sequence. Of course if you want to select random enemies from a pool of prefabs you could simple swap out the single prefab reference with an array and pick a random one like @QuantumCookies showed in his answer.
Note that this spawner is a blind spawner purely based on time. It does not wait for all enemies to be destroyed. Of course for something like boss fights this might be required. However this is currently not supported.
One more question though, how would I print out (in the console) what wave is starting? When I try to print the current wave i get "WaveGenerator + Wave"
Well m_CurrentWave holds the Wave object instance of the current wave, Each wave has a nave that can be set in the inspector. So you can print m_CurrentWave.name
. If you're looking for some kind of index or wave number, currently there isn't such a thing since the spawner is an endless spawner and would repeat the wave sequance with increased difficulty (simply reduced delay). If you want a wave counter you would need to create your own int variable which you increment by one when a new wave starts.
Answer by QuantumCookies · Jul 24, 2020 at 07:01 AM
Well you could try approaching it like this.
In the Wave class is where you storing the variable to hold the enemy that you are spawning. Instead replace it by creating an array or list array as follows. This will allow you to put multiple enemy prefabs to spawn.
public GameObject[] Enemies;
And then you can spawn these enemies at random similar to how you've created the different spawn points for the enemy to spawn at.
public void SpawnEnemy()
{
int randomEnemy = Random.Range(0, Enemies.Length); //Selecing a random enemy
Transform _sp = spawnPoints[Random.Range(0, spawnPoints.Length)];
Instantiate(Enemies[randomEnemy], _sp.position, _sp.rotation);
}
Hope this helps!
Your answer
Follow this Question
Related Questions
Enemy Spawn System with time and limit enemy in game 2 Answers
Spawn waves & wait till it's killed, spawn again. 1 Answer
How to spawn objects but set a cap of how many can be alive at the same time? 0 Answers
simple waypoint system enemy wave spawner 1 Answer
How to increase int every 5 waves? 1 Answer