Unity Has Started Crashing because of a EnemyController script using NavMesh

Hello everyone, i have no idea why this has started happening, it literally happened overnight and i DID NOT touch the script yesterday, this morning when i opened my project and started testing stuff It started displaying errors such as:

  • StackOverFlowException: The requested operation caused a stack overflow.
  • TLS Allocator ALLOC_TEMP_THREAD, underlying allocator ALLOC_TEMP_THREAD has unfreed allocations, size 470

the only thing i added now was a bunch of debug logs to find out at wich point it crashes, and i think
there could be a problem in the ChangeZombiStatus Method.

I can provide the other scripts linked to EnemyController if needed.

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

public class EnemyController : MonoBehaviour
{
    public enum EnemyState
    {
        Locked, Idle, Locomotion, Reaction, Action, Death
    }

    public EnemyState startingStatus;
    public EnemyState currentStatus;


    private EnemyReaction _reaction;
    private EnemyLocomotion _locomotion;
    private EnemyAction _action;
    private Animator _animator;
    private NavMeshAgent _agent;

    private EnemyStatus currentZombieStatus;
    public PlayerController _player { get; set; }
    public float Chaserange = 10;

    private void Awake()
    {

        _animator = GetComponentInChildren<Animator>();
        _agent = GetComponent<NavMeshAgent>();

        _locomotion = GetComponent<EnemyLocomotion>();
        _locomotion.Init(this);

        _reaction = GetComponent<EnemyReaction>();
        _reaction.Init(this);

        _action = GetComponent<EnemyAction>();
        _action.Init(this);
    }

    private void OnEnable()
    {
        _player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>();
      

    }

    private void OnDisable()
    {
        _player = null;
       
    }

    private void Start()
    {
        _player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>();
        ChangeZombieStatus(startingStatus);
       
    }

    private void Update()
    {
        ExecuteStatus();

        //_animator.SetBool("on_ground", !_agent.isOnOffMeshLink);
        _animator.SetFloat("speed", _agent.velocity.magnitude);
       
    }


    public void LockZombie()
    {
        //Startingstatus = ZombieStatus.Locked;
        ChangeZombieStatus(EnemyState.Locked);
        //if(_chase != null)
        //    _chase.enabled = false;
        //if (_locomotion != null)
        //_locomotion.enabled = false;
       
    }



    public void UnlockZombie()
    {
        //if (_chase != null)
        //    _chase.enabled = true;
        //if (_locomotion != null)
        //    _locomotion.enabled = true;
        ChangeZombieStatus(EnemyState.Idle);
       
    }



    public void ChangeZombieStatus(EnemyState newStatus)
    {
        //Here is where Unity Crashes i think
       
        if (currentStatus != newStatus)
        {
            if (currentZombieStatus != null)
            {
                Debug.Log("Crash if CurrentStatus != null");
                currentZombieStatus.OnStatusExit();
                currentZombieStatus = null;
            }


            currentStatus = newStatus;

            _locomotion.enabled = false;
            _reaction.enabled = false;
            _action.enabled = false;

            switch (currentStatus)
            {
               
                case EnemyState.Locomotion:
                    Debug.Log("Crash CurrentStatus Case Locomotion");
                    _locomotion.enabled = true;
                    currentZombieStatus = _locomotion;
                    break;
                case EnemyState.Reaction:
                    Debug.Log("Crash CurrentStatus Case Reaction");
                    _reaction.enabled = true;
                    currentZombieStatus = _reaction;
                    break;
                case EnemyState.Action:
                     //The crash might be here more spefically
                    Debug.Log("Crash CurrentStatus Case Action");
                    _action.enabled = true;
                    currentZombieStatus = _action;
                    break;
                default:
                    Debug.Log("Crash CurrentStatus Case null");
                    currentZombieStatus = null;
                    break;

            }

            if (currentZombieStatus != null)
            {
                //The crash might be here more spefically
                Debug.Log("Crash CurrentStatus");
                currentZombieStatus.enabled = true;
               currentZombieStatus.OnStatusEnter();
            }

        }
    }


    void ExecuteStatus()
    {
        Debug.Log("Crash ExecuteStatus");
        if (currentStatus == EnemyState.Locked) return;

        if (currentStatus == EnemyState.Action)
        {
            return;
        }

        if (_player)
        {
            float distance = Vector3.Distance(transform.position, _player.transform.position);
            if (distance <= Chaserange)
            {
                ChangeZombieStatus(EnemyState.Reaction);
            }
            else
            {
                ChangeZombieStatus(EnemyState.Locomotion);
            }

            return;
        }

        if (currentStatus == EnemyState.Idle)
        {
            ChangeZombieStatus(EnemyState.Locomotion);
        }

    }
}

This tells you where the stackoverflow occured. Just look at the provided callstack, and you’ll see where (line numbers, most callstack entries should be hyperlinked). If not, it might be within Unity’s own code but at least you’ll see which of your methods (if any) made that call.

1 Like

Also note then when talking about a “crash”; that typically means that the Unity Editor application closes and presents you with the bug reporter tool. What you’re seeing here is C# reporting an exception thrown executing your script and presumably the Unity Editor application isn’t exiting.

An exception normally shows you where it was thrown i.e. the call-site where it was thrown and the whole callstack should be available in most cases.

Attach a debugger and run it and it’ll stop there.

1 Like

I’ll guess that you’ve somehow cross-linked your inter-object events (which I’m guessing get hooked up in your various Init(this) calls) into an endless loop.

As Melv says, hook up the debugger and step through… most likely you are ping-ponging ceaselessly between two states, or repeated settings of a single state.

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.