- Home /
How would I go about making infinite waves that get harder over time?
I have a script but I want to know how I can modify it to make infinite waves that get harder as you go on. This is my current wave spawner script:
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class Wave
{
public string waveName;
public int noOfEnemies;
public GameObject[] typeOfEnemies;
public float spawnInterval;
}
public class WaveSpawner : MonoBehaviour
{
public Wave[] waves;
public Transform[] spawnPoints;
public Animator animator;
public Text waveName;
private Wave currentWave;
private int currentWaveNumber;
private float nextSpawnTime;
private bool canSpawn = true;
private bool canAnimate = false;
public AudioClip winMusic;
public GameObject winMenu;
float playsLeft = 1f;
private void Update()
{
currentWave = waves[currentWaveNumber];
SpawnWave();
GameObject[] totalEnemies = GameObject.FindGameObjectsWithTag("Enemy");
if (totalEnemies.Length == 0)
{
if (currentWaveNumber + 1 != waves.Length)
{
if (canAnimate)
{
waveName.text = waves[currentWaveNumber + 1].waveName;
animator.SetTrigger("WaveComplete");
canAnimate = false;
}
}
else
{
if(playsLeft >= 1f)
{
winMenu.SetActive(true);
GameObject.FindGameObjectWithTag("Music").GetComponent<AudioSource>().Stop();
GameObject.FindGameObjectWithTag("Music").GetComponent<AudioSource>().PlayOneShot(winMusic);
playsLeft--;
}
}
}
}
void SpawnNextWave()
{
currentWaveNumber++;
canSpawn = true;
}
void SpawnWave()
{
if (canSpawn && nextSpawnTime < Time.time)
{
GameObject randomEnemy = currentWave.typeOfEnemies[Random.Range(0, currentWave.typeOfEnemies.Length)];
Transform randomPoint = spawnPoints[Random.Range(0, spawnPoints.Length)];
Instantiate(randomEnemy, randomPoint.position, Quaternion.identity);
currentWave.noOfEnemies--;
nextSpawnTime = Time.time + currentWave.spawnInterval;
if (currentWave.noOfEnemies == 0)
{
canSpawn = false;
canAnimate = true;
}
}
}
}
Answer by rage_co · Jul 26, 2021 at 07:23 AM
you should start by creating a single starting wave and write a script to generate the next wave...i can give you an headstart here
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public class Wave
{
public string waveName;
public int noOfEnemies;
public GameObject[] typeOfEnemies;
public float spawnInterval;
}
public class WaveSpawner : MonoBehaviour
{
public Wave[] waves;
public Transform[] spawnPoints;
public Animator animator;
public Text waveName;
private Wave currentWave;
Wave activeWave;
Wave nextWave;
public int enemyIncrement;
public int incrementRandom;
private int currentWaveNumber;
private float nextSpawnTime;
private bool canSpawn = true;
private bool canAnimate = false;
public AudioClip winMusic;
public GameObject winMenu;
float playsLeft = 1f;
private void Update()
{
activeWave = currentWave;
SpawnWave();
GameObject[] totalEnemies = GameObject.FindGameObjectsWithTag("Enemy");
if (totalEnemies.Length == 0)
{
if (currentWaveNumber + 1 != waves.Length)
{
if (canAnimate)
{
waveName.text = waves[currentWaveNumber + 1].waveName;
animator.SetTrigger("WaveComplete");
canAnimate = false;
}
}
else
{
if(playsLeft >= 1f)
{
winMenu.SetActive(true);
GameObject.FindGameObjectWithTag("Music").GetComponent<AudioSource>().Stop();
GameObject.FindGameObjectWithTag("Music").GetComponent<AudioSource>().PlayOneShot(winMusic);
playsLeft--;
}
}
}
}
void SpawnNextWave()
{
CreateNextWave();
currentWave = nextWave;
currentWaveNumber ++;
canSpawn = true;
}
void SpawnWave()
{
if (canSpawn && nextSpawnTime < Time.time)
{
GameObject randomEnemy = activeWave.typeOfEnemies[Random.Range(0, activeWave.typeOfEnemies.Length)];
Transform randomPoint = spawnPoints[Random.Range(0, spawnPoints.Length)];
Instantiate(randomEnemy, randomPoint.position, Quaternion.identity);
activeWave.noOfEnemies--;
nextSpawnTime = Time.time + activeWave.spawnInterval;
if (activeWave.noOfEnemies == 0)
{
canSpawn = false;
canAnimate = true;
}
}
}
void CreateNextWave()
{
Wave newWave = new Wave();
int newWaveNumber = currentWaveNumber + 1;
newWave.waveName = "Wave " + newWaveNumber;
int newEnemyNo = NewWaveEnemyNumber(2, currentWave.noOfEnemies);
newWave.typeOfEnemies = currentWave.typeOfEnemies;
newWave.spawnInterval = currentWave.spawnInterval;
nextWave = newWave;
}
int NewWaveEnemyNumber(int cycles, int currentNumber)
{
if(cycles > 0)
{
int number = currentNumber + Random.Range(enemyIncrement - incrementRandom, enemyIncrement + incrementRandom);
if(cycles > 1)
{
return(NewWaveEnemyNumber(cycles - 1, number));
}
else
{
return(number);
}
}
else
{
return(currentNumber);
}
}
}
Considering your script works right now, this script here, allows you to increase the number of enemies in every wave in any way you want, if you start the NextWaveEnemyNumber() method here with 1 cycle, the result will be a linear expansion (not counting the randomness)...aka not a very big and generally a similar increase per wave like 1 enemy in wave 1, 2 in wave 2, 3 in wave 3 etc...you can increase the number of cycles to create exponential increase, which makes for a more dynamic and challenging mechanic, and if you set it to 0, there will be no increase at all. As for enemy types, you will need to separate them based on tiers or things like that and create something similar from scratch....i don't know exactly what to do here, so i left it upon you do create a type system that suits your needs...Hope this helps!
I just remembered that using a while loop would definitely have been better...so you can modify it to include that