Home > Software design >  How can i modify code to spawn enemies every 30 seconds only if there is less than 10 enemies
How can i modify code to spawn enemies every 30 seconds only if there is less than 10 enemies

Time:01-20

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

  •  Tags:  
  • Related