Enemy Wave Generator Spawn System Help!

Am developing a spaceShooter(3D Game) and got in to a wall. Am trying to create a enemy Spawn waves which will spawn 3 different types of enemies as listed below, infinitely. There will be 4 waves, each wave will spawn enemy prefabs in a timely manner. Once all the four waves get completed again it get looped so basically it will be infinite 4 waves and speed of spawn increases after each 4 waves.

Remember please am in a learning curve, I need an efficient way to structure the below logic… I knew it is not an efficient manner and would like to structure the concept in an efficient manner. I do have done lot of research and found many wave generators most of which is not similar to the one am looking for… So, please help me out here. Thanks a lot for your time and Happy Coding!

enemy prefabs
basicEnemyShip prefab
mediumEnemyShip Prefab
Boss EnemyShip Prefab

Waves of enemies

First Wave
Second Wave
Third Wave
Fourth Wave

First Wave
{
  Timer 20 Sec 
  Instantiate basic enemy prefab(N Numbers)
  Timer 25 Sec
  Instantiate mediumEnemyShip (N Numbers)
  Timer 30 Sec
  Instantiate BossEnemyShip Prefab
}

Second Wave
{
  Timer 30 Sec
  Instantiate basic enemy prefab (N numbers)
  Timer 35 Sec
  Instantiate Medium EnemyShip (N Numbers)
  Timer 30 Sec
  Instantiate BossEnemyShip Prefab
}

Third Wave
{
  Timer 40 Second
  Instantiate basic enemy prefab + mediumEnemyShip (N numbers Random Numbers)
  Timer 30 Second
  Instantiate bossEnemyShip Prefab

}

Fourth Waves
{
  Timer 50 Second
  Instantiate mediumEnemyShip+BossEnemyShip
  Timer 40 Second
  Instantiate BossEnemyShip
}

Wave loops
{
  First Wave
  
  Second Wave
  
  Third Wave
  
  Fourth Wave
}


Enemy spawn Amount increases end of each loops (4 waves)
enemy speed increases end of each loops (4 waves)

I just had nothing else to do, so i wrote a simple wave generator :wink:

// C#
// WaveGenerator.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class WaveAction
{
	public string name;
	public float delay;
	public Transform prefab;
	public int spawnCount;
	public string message;
}

[System.Serializable]
public class Wave
{
	public string name;
	public List<WaveAction> actions;
}



public class WaveGenerator : MonoBehaviour
{
	public float difficultyFactor = 0.9f;
	public List<Wave> waves;
	private Wave m_CurrentWave;
	public Wave CurrentWave { get {return m_CurrentWave;} }
	private float m_DelayFactor = 1.0f;

	IEnumerator SpawnLoop()
	{
		m_DelayFactor = 1.0f;
		while(true)
		{
			foreach(Wave W in waves)
			{
				m_CurrentWave = W;
				foreach(WaveAction A in W.actions)
				{
					if(A.delay > 0)
						yield return new WaitForSeconds(A.delay * m_DelayFactor);
					if (A.message != "")
					{
						// TODO: print ingame message
					}
					if (A.prefab != null && A.spawnCount > 0)
					{
						for(int i = 0; i < A.spawnCount; i++)
						{
							// TODO: instantiate A.prefab
						}
					}
				}
				yield return null;  // prevents crash if all delays are 0
			}
			m_DelayFactor *= difficultyFactor;
			yield return null;  // prevents crash if all delays are 0
		}
	}
	void Start()
	{
		StartCoroutine(SpawnLoop());
	}

}

This allows you to define as many waves you like and each wave can have mutiple spawn actions each with a custom delay. You can also spawn multiple different prefabs at the same time by setting the delay of subsequent actions to 0. You can also use this to just print a message by not assigning a prefab but only a message.

It’s a quite “hacky” solution but quite versatile and easy to extend.

Here’s how it looks like in the inspector where you would define your waves:


edit
I forgot that you wanted to lower the delay each iteration. I’ve added a simple factor which is lowered each iteration by 10% (times 0.9). So during the first iteration the factor is 1.0 during the next iterations it will be 0.9 | 0.81 | 0.729 | … always 10% of the previous iteration

@Bunny83 Ok, lets try that again.
First off, I’m sorry, it was not my intention to necro post, or to come off as not understanding the code.
Second, I was able to fix the errors I mentioned previously.
The game I am working on is to have different types of enemies spawn in. I have a regular enemy, a fast enemy, a boss enemy, and mini enemies that are summoned via the boss.
The issue I was running into prior at looking at this forum was that the enemies would spawn immediately as soon as the wave started. I also have a UI system In place to display the current wave and to give the player a few seconds before the enemies actually start moving.
My goal was to have the UI system say “This is the current wave, ready go!” and then the enemies would start moving.
I am simply building upon the tutorial that I was working on Unity Learn, I can post a link to it in the message board, but I was trying to flesh it out to give it more features.
I wrote a script prior to looking into this one, and it worked in the sense that enemies would spawn, but only 1 enemy would spawn per wave, and the boss enemy would not spawn mini enemies when it got to the boss round, so there is no increase in challenge.
I have been trying to figure this out for a few weeks, and I was not able to come up with any concrete results on how to get it to function to my specifications.
The objective I’m trying to reach is have my wave Ui system alert the player whenever a new wave begins and when one is completed after defeating the specified number of enemies.
I understand that you are busy and that you are taking time out of your day to assist anyone who may have questions on how to get a functioning enemy wave spawn system.
I understand the more features and concepts I add to the game, the more complex the code will be in regards to have it function the way I want it to.
I am simply looking for a way to get the enemy prefabs I’ve created to spawn in correctly.
In regards to your previous post I do again wish to apologize.
Originally I had 4 coroutines set up to spawn in the main enemy, the boss, spawn mini enemies during the boss phase, and to track and remaining enemies before moving onto the next wave.

Here’s a working script with TMP & Randoms added :slight_smile:

WaveGenerator.cs




using UnityEngine;  

using System.Collections;  

using System.Collections.Generic; 

using TMPro;  // added for Text Mesh Pro

[System.Serializable]
public class WaveAction
{
    public string name;
    public float delay;
    public Transform prefab;
    public int spawnCount;
    public string message;
}

[System.Serializable]
public class Wave
{
    public string name;
    public List<WaveAction> actions;
}



public class WaveGenerator : MonoBehaviour
{
    public float difficultyFactor = 0.9f;
    public List<Wave> waves;
    private Wave m_CurrentWave;
    public Wave CurrentWave { get { return m_CurrentWave; } }
    private float m_DelayFactor = 1.0f;
    public TMP_Text textElement; // printing the messages on Text Mesh Pro Element
    public float lowestRangeX = 50.0f; // minimum spawn area on x axis
    public float highestRangeX = 50.0f; // maximum spawn area on x axis
    public float lowestRangeZ = 50.0f; // minimum spawn area on z axis
    public float highestRangeZ = 50.0f; // maximum spawn area on z axis
    public float lowestRangeY = 0.0f; // minimum prefab rotation on y axis
    public float highestRangeY = 360.0f; // maximum prefab rotation on z axis

    IEnumerator SpawnLoop()
    {
        m_DelayFactor = 1.0f;
        while (true)
        {
            foreach (Wave W in waves)
            {
                m_CurrentWave = W;
                foreach (WaveAction A in W.actions)
                {
                    if (A.delay > 0)
                        yield return new WaitForSeconds(A.delay * m_DelayFactor);
                    if (A.message != "")
                    {
                        textElement.text = A.message;  // print the message to a Text Mesh Pro Element on a Canvas
                    }
                    if (A.prefab != null && A.spawnCount > 0)
                    {
                        for (int i = 0; i < A.spawnCount; i++)
                        {
                            // update the x & z values depending on the specific boundaries of your scene
                            Vector3 randomizePosition = new Vector3(Random.Range(lowestRangeX, highestRangeX), 0, Random.Range(lowestRangeZ, highestRangeZ));

                            // update the y values depending on how much you want the prafabs to randomly rotate
                            Quaternion randomizeRotation = Quaternion.Euler(0, Random.Range(lowestRangeY, highestRangeY), 0);

                            A.prefab = Instantiate(A.prefab, randomizePosition, randomizeRotation);
                        }
                    }
                }
                yield return null;  // prevents crash if all delays are 0
            }
            m_DelayFactor *= difficultyFactor;
            yield return null;  // prevents crash if all delays are 0
        }
    }
    void Start()
    {
        StartCoroutine(SpawnLoop());
    }
}