How can i rework this script to make enemies spawn at different times and amounts?

I want to be able to make the enemies within the scene spawn randomly at different times and amounts. At the moment my script makes the enemies spawn in the map all at once at random positions. If anyone could help me add to this script and make it so that the enemies would spawn at different amounts and times would be appreciated.

public class RandomEnemySpawn : MonoBehaviour {

public GameObject Enemies;
public int xPos;
public int zPos;
public int EnemyNumber;

void Start()
{
    StartCoroutine(EnemySpawn());
}

IEnumerator EnemySpawn()
{
    while (EnemyNumber < 5) 
    {
        xPos = Random.Range(5, 500);
        zPos = Random.Range(5, 540);
        Instantiate(Enemies, new Vector3(xPos, 1, zPos), Quaternion.identity);
        yield return new WaitForSeconds(0.1f);
        EnemyNumber += 1;
    }

}

}

To do this you would need to have two “States” The first is the spawn enemy state, which has a corresponding enemy number to spawn. Then you would have to have a wait to spawn state, which starts at random times. There are a couple of ways to do this but since you are already using coroutines might as well go with that route.


First, you would need an enemy spawn manager. This will run until the end of the game or scene.
Then you will need an enemy spawner, which will only run while the enemies are spawning.
It would look something like this(somewhat a pseudo code, you will need to rework it to get it to work for you)
public class RandomEnemySpawn: MonoBehaviour
{
    //is spawning active? this gives you a way to exit the coroutine once its started(always do this in looped coroutines)
    public bool spawningActive;

    //this manages spawn times
    IEnumerator EnemeySpawnManager()
    {
        //the loop!
        while(spawningActive)
        {
            //wait a random amount of time before spawning a new set of enemies
            yield return new WaitForSeconds(Random.Range(0.1f, 0.5f));
            //start another coroutine and wait for it to finish(prevents stacking)
            yield return EnemySpawn(Random.Range(1, 5), Random.Range(0.05f, 0.15f));
        }
    }
    //This will spawn a number of enemies with a given wait time between each
    IEnumerator EnemySpawn(int number, float wait)
    {
        for(int i = 0; i < number; i++)
        {
            //your function for spawning an enemy at a random location
            SpawnEnemy();
            yield return new WaitForSeconds(wait);
        }
    }
}

Don't just copy and past try and figure out how this design works before using it! It is best to actually understand something before using it, this will allow you to adjust it or use a similar pattern later on for a different, but similar problem.