Recursive method is causing a Stack Overflow Exception

I’m trying to spawn enemies randomly from an array of enemies. I’m using an if else statement to check if the enemy should be spawned or not. It was all working fine, until I added another argument in the if else statement to check if there are more enemies of a certain type than the specified limit. So I don’t want 50 enemies of the same type to spawn and stuff like that so I added a limit and a way to count them using tags in the if else statement. I have tried many solutions but nothing works… Here is the code of the enemy spawner:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySpawner : MonoBehaviour
{
    [SerializeField] Enemy[] enemies = null;
    [SerializeField] float timeTilEachSpawn = 3;
    [SerializeField] int maxEnemyCount = 10;
    [SerializeField] GameObject player = null;

    public static int count = 0;

    int previousScore = 0;
    Vector2 enemyPosition;
    float minY = -4f;
    float maxY = 4f;

    private void Start()
    {
        StartCoroutine(spawnEnemies());
    }

    private void Update()
    {
        if (timeTilEachSpawn != 1)
            checkScoreForSpawnLevel();
    }

    IEnumerator spawnEnemies()
    {
        while(true)
        {
                yield return new WaitForSeconds(timeTilEachSpawn);
                spawnEnemy();      
            }
    }

    void spawnEnemy()
    {
        if (count < maxEnemyCount)
        {
            if(player.transform.position.y >= 0)
            {
                minY = 0;
                maxY = 4;
            }

            else
            {
                minY = -4;
                maxY = 0;
            }

            enemyPosition = new Vector2(transform.position.x, Random.Range(minY, maxY));
            int enemyIndex = Random.Range(0, enemies.Length);
            Enemy enemy = enemies[enemyIndex];

            //Problem Here :)
            if(Random.value > enemy.getSpawnChance() && ScoreManager.getScore() >= enemy.getScoreToSpawn() && GameObject.FindGameObjectsWithTag(enemy.tag).Length < enemy.getSpawnLimit())
            {
                Instantiate(enemy, enemyPosition, Quaternion.identity);
                Debug.Log(enemy.getScoreToSpawn());
                Debug.Log(enemy.getHealth());
                count++;
            }
         
            else
            {
                spawnEnemy();
            }
        }    
    }

    void checkScoreForSpawnLevel()
    {
        if (ScoreManager.getScore() - previousScore == 5)
        {
            previousScore = ScoreManager.getScore();
            timeTilEachSpawn -= 0.1f;
        }
    }
}

The problem is from the spawnEnemy() method since its recursive. Any help is deeply appreciated :slight_smile:

Well you’re ANDing 3 conditions together. If any of them are false you will always fall into the else block which makes the recursive call. Figure out which one(s) are staying false. Debug.Log is your best friend. Separating each boolean condition out into a separate line and local variable will also make debugging and reading the code easier.

2 Likes

Thanks I fixed it by checking beforehand if the count equals the limit or higher then the index of the enemy will change randomly to a different one :slight_smile:

            if (GameObject.FindGameObjectsWithTag(enemy.tag).Length >= enemy.getSpawnLimit())
            {
                enemyIndex = randomNumberExcept(0, enemies.Length, enemyIndex);
                enemy = enemies[enemyIndex];
            }    

            if (Random.value > enemy.getSpawnChance() && ScoreManager.getScore() >= enemy.getScoreToSpawn())
            {
                Instantiate(enemy, enemyPosition, Quaternion.identity);
                count++;
            }
         
            else
            {
                spawnEnemy();
            }