First time posting. I’ve been learning Unity over the last couple months and things are going good. Learning a lot. But I have run into a roadblock and I’d like to ask for help.
I’ve got a game where enemies are separated into 2 categories(stationary, and mobile), and spawn between preset spawn points of the same categories. I’ve used the Brackeys spawn wave tutorial as a base and have edited it to allow waves to select enemies at random, and an if else to determine if it spawns at a stationary or mobile spawn point. Problem is enemies tend to spawn at the same location overlapping onto themselves during a wave which is undesirable.
I think I need a list, and when a spawn point is selected at random it’s then stored in a list to then be excluded in future spawn points? Then at the beginning of a new wave delete the stored entries in the list. Rinse, repeat.
I am not entirely sure how to go about this however. Any help welcome. Thanks!
==EDIT==
I got busy and was working on other stuff but I did come back to this and it was a lot easier than I originally thought. I just used a checksphere and with a few lines of code it works so much better than any kind of convoluted list.
if (Physics.CheckSphere(s_Spawn.position, 1f, hittableLayers))
{
Debug.Log(“Can’t spawn here”);
return;
}
else
{
Debug.Log("Spawning enemy: " + stationaryEnemies[randomEnemy].name);
Instantiate(stationaryEnemies[randomEnemy], s_Spawn.position, s_Spawn.rotation);
}
using System.Collections;
using UnityEngine;
public class WaveController : MonoBehaviour
{
public enum SpawnState { SPAWNING, WAITING, COUNTING};
[System.Serializable]
public class Wave
{
public string name;
public int count;
public float rate;
}
public GameObject[] mobileEnemies;
public GameObject[] stationaryEnemies;
public Wave[] waves;
private int nextWave = 0;
public Transform[] mobileSpawnPoints;
public Transform[] stationarySpawnPoints;
//private List<int> mobilePreviousSpawnPoint;
//private List<int> stationaryPreviousSpawnPoint;
public float timeBetweenWaves = 5f;
private float waveCountdown;
private float searchCountDown = 1f;
private SpawnState state = SpawnState.COUNTING;
void Start()
{
waveCountdown = timeBetweenWaves;
}
void Update()
{
if(state == SpawnState.WAITING)
{
if (!EnemyIsAlive())
{
WaveCompleted();
}
else
{
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;
if(nextWave + 1 > waves.Length - 1)
{
nextWave = 0;
Debug.Log("All waves complete! Looping...");
}
else
{
nextWave++;
}
}
bool EnemyIsAlive()
{
searchCountDown -= Time.deltaTime;
if(searchCountDown <= 0f)
{
searchCountDown = 1f;
if (GameObject.FindGameObjectWithTag("Enemy") == null)
{
return false;
}
}
return true;
}
}
IEnumerator SpawnWave(Wave _wave)
{
Debug.Log("Spawning Wave: " + _wave.name);
state = SpawnState.SPAWNING;
for (int i = 0; i < _wave.count; i++)
{
int randomEnemySelect = Random.Range(0, 10);
if (randomEnemySelect >= 5)
{
SpawnMobileEnemy();
}
else
{
SpawnStationaryEnemy();
}
yield return new WaitForSeconds(1f / _wave.rate);
}
state = SpawnState.WAITING;
yield break;
}
void SpawnMobileEnemy()
{
int randomEnemy = Random.Range(0, mobileEnemies.Length);
Transform m_Spawn = mobileSpawnPoints[Random.Range(0, mobileSpawnPoints.Length)];
Debug.Log("Spawning enemy: " + mobileEnemies[randomEnemy].name);
Instantiate(mobileEnemies[randomEnemy], m_Spawn.position, m_Spawn.rotation);
}
void SpawnStationaryEnemy()
{
int randomEnemy = Random.Range(0, stationaryEnemies.Length);
Transform s_Spawn = stationarySpawnPoints[Random.Range(0, stationarySpawnPoints.Length)];
Debug.Log("Spawning enemy: " + stationaryEnemies[randomEnemy].name);
Instantiate(stationaryEnemies[randomEnemy], s_Spawn.position, s_Spawn.rotation);
}
}