Code Crystal Vanguard

Problem

The problem was that the enemies waited until the group before them was done with all the spawning before they started spawning. So I could only spawn 1 group at a time. And that's a big deal, because let's say if I constantly spawn a group and I want to spawn a boss in between the spawning of the group, that wouldn't be possible.

                                
private IEnumerator SpawnUnits()
{
    foreach(SpawnInfo group in spawnInfo)
    {
        //Code for spawning
        int currentSpawnAmountLeft = group.spawnAmount;
        yield return new WaitForSeconds(group.firstUnitSpawnTime);
        for (int i = 0; i < group.spawnAmount; i++)
        {
            if (currentSpawnAmountLeft <= 0)
            {
                yield return null;
            }
            GameObject newUnitGO = Instantiate
            (group.enemyUnitGroup, spawnLocations.position, spawnLocations.rotation);
            Unit newUnit = newUnitGO.GetComponent<Unit>();
            newUnit.SetFaction(0); // 0 are the enemies, 1 are the friendlies
            enemyUnits.Add(newUnit);
            currentSpawnAmountLeft -= 1;
            yield return new WaitForSeconds(group.delayBetweenSpawns);
        }
    }
    yield return null;
}
                                
                            

Solution

The solution is to go in a second coroutine and spawn the enemies there. Different from how it was, now every group starts its own coroutine. And I just give the variable of the foreach to the second coroutine so it still knows its data from the struct.

                                
private IEnumerator SpawnUnits()
{
    foreach(SpawnInfo group in spawnInfo)
    {
        StartCoroutine(PerGroup(group));
    }
    yield return null;
}

private IEnumerator PerGroup(SpawnInfo group)
{
    //Code for spawning
}
                                
                            

The Full Script
|
v


                                
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class SpawnManager : MonoBehaviour
{
    // Instantiating this script
    public static SpawnManager Instance { get; private set; }

    public List<Transform> spawnLocations = new();
    public List<Unit> enemyUnits = new();

    public List<SpawnInfo> spawnInfo = new();

    private void Awake()
    {
        // Making it a singleton
        if (Instance == null)
        {
            Instance = this;
        } 
        else
        {
            Debug.LogError("Another SpawnManager is in the scene!!");
        }
    }

    private void Start()
    {
        StartCoroutine(SpawnUnitGroups());
    }

    private IEnumerator SpawnUnitGroups()
    {
        foreach(SpawnInfo group in spawnInfo)
        {
            StartCoroutine(PerGroup(group));
        }
        yield return null;
    }

    private IEnumerator PerGroup(SpawnInfo group)
    {
        // Code for spawning each enemy
        int currentSpawnAmountLeft = group.spawnAmount;
        yield return new WaitForSeconds(group.firstUnitSpawnTime);
        for (int i = 0; i < group.spawnAmount; i++)
        {
            if (currentSpawnAmountLeft <= 0)
            {
                yield return null;
            }
            GameObject newUnitGO = Instantiate
            (group.enemyUnitGroup, spawnLocations[0].position, spawnLocations.rotation);
            Unit newUnit = newUnitGO.GetComponent<Unit>();
            newUnit.SetFaction(0); // 0 are the enemies, 1 are the friendlies
            enemyUnits.Add(newUnit);
            currentSpawnAmountLeft -= 1;
            yield return new WaitForSeconds(group.delayBetweenSpawns);
        }
        yield return null;
    }
}