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);


    }

}

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!

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.