How can i modify code on unity c# to spawn enemies every 30 seconds only if there is less than 10 enemies on the field.
At the moment i have a while loop inside an enumerator that spawns enemies to 10 but is only called in the beginning, i need the function to spawn enemies, when the amount of enemies reaches 1.
Thanks.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GenerateEnemies : MonoBehaviour
{
public GameObject theEnemy;
public int xPos;
public int zPos;
public int enemyCount;
void Start()
{
StartCoroutine(SpawnEnemy());
}
IEnumerator SpawnEnemy()
{
while (enemyCount < 10)
{
xPos = Random.Range(153, 203);
zPos = Random.Range(-76, 76);
Instantiate(theEnemy, new Vector3(xPos, 9, zPos), Quaternion.identity);
yield return new WaitForSeconds(0.9f);
enemyCount = 1;
}
}
}
CodePudding user response:
I haven't tested this code at all
Hi Obito, let me show you this code and see if you can implement it:
[Header("Spawning Properties")]
public GameObject enemyPrefab;
public Vector3 spawnPoint;
public int maxEnemies = 10;
public int minEnemies = 1;
//This is the time between each spawn.
public float spawnDelay = 0.9f;
public spawnTimer = 30f;
//Every enemy *needs* an 'Enemy' script, or tag, to identify what is an enemy.
public int EnemyCount => GameObject.FindObjectsOfType<Enemy>();
private void Awake()
{
spawnTimer = 30f;
}
private void Update()
{
spawnTimer -= Time.deltaTime;
//"Do I need to start spawning enemies?"
if(EnemyCount <= minEnemies && spawnTimer <= 0) {
StartCoroutine(SpawnEnemies());
}
}
private IEnumerator SpawnEnemies()
{
while(EnemyCount <= maxEnemies)
{
Instantiate(enemyPrefab, spawnPoint, Quaternion.identity);
yield return new WaitForSeconds(spawnDelay);
Debug.Log("Enemy " EnemyCount "/" maxEnemies " spawned.");
}
spawnTimer = 30f;
}
Tip: If you want to make a "enemies per wave" system, you should try doing this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[Header("Spawning Properties")]
public GameObject enemyPrefab;
public Vector3 spawnPoint;
public int[] wavesCount = { 10, 14, 23, 40 };
public int minEnemiesPerWave = 1;
public int currentWave = 0;
//This is the time between each spawn.
public float spawnDelay = 0.9f;
private float spawnTimer = 30f;
//Every enemy *needs* an 'Enemy' script, or tag, to identify what is an enemy.
public int EnemyCount => GameObject.FindObjectsOfType<Enemy>();
private void Start() {
spawnTimer = 30f;
}
private void Update()
{
spawnTimer -= Time.deltaTime;
//"Do I need to start spawning enemies?"
if(EnemyCount <= minEnemiesPerWave && spawnTimer <= 0) {
StartCoroutine(SpawnEnemies());
}
}
private IEnumerator SpawnEnemies()
{
while(EnemyCount <= wavesCount[currentWave])
{
Instantiate(enemyPrefab, spawnPoint, Quaternion.identity);
yield return new WaitForSeconds(spawnDelay);
Debug.Log("Enemy " EnemyCount "/" maxEnemies " spawned.");
}
spawnTimer = 30f;
currentWave ;
}
}
CodePudding user response:
Simply wrap your code in an endless loop and do e.g.
public class GenerateEnemies : MonoBehaviour
{
public GameObject theEnemy;
public int xPos;
public int zPos;
public int enemyCount;
IEnumerator Start()
{
// As long as you yield within this is totally fine in an IEnumerator
while(true)
{
// If there is already 10 or more
if(enemyCount >= 10)
{
// wait a frame and check again
yield return null;
continue;
}
xPos = Random.Range(153, 203);
zPos = Random.Range(-76, 76);
Instantiate(theEnemy, new Vector3(xPos, 9, zPos), Quaternion.identity);
enemyCount ;
// waiting 30 seconds then check again
yield return new WaitForSeconds(30);
}
}
}
Assuming of course that enemyCount is somewhere reduced from the outside.
Or from what you say you wan to additionally wait until the amount reaches 1 and then start spawning again so you could add
...
enemyCount ;
if(enemyCount >= 10)
{
yield return new WaitUntil(() => enemyCount <= 1);
}
else
{
yield return new WaitForSeconds(30);
}
...
So you wait 30 seconds between spawning enemies but once you reach 10 enemies you wait until the amount is again reaching 1 or less
