Having issues with state machine and stack overflows

I am currently making a small test game as a way to learn AI and state machines.
I have looked at few tutorials and videos on the theory, but t seems like my attempt isn’t working quite right.

My main issues are twofold:

  • Line 8 (where I create an instance of one of the state objects), it creates a stack overflow and I cannot for the life of me figure out what’s causing it.

  • When running, I get the nullref error. I can’t understand why the code doesn’t have any references, as again, I create new object instances in the script.
    I am missing something, but I cannot tell what it is, so if someone has an answer I would appreciate it!

The code is as follows:

State Machine Controller

public class StateControllerCompanion : MonoBehaviour
{
    WolfCompanionDefaultState currentState;
    public  WolfCompanionBeingPettedState wolfCompanionBeingPettedState = new WolfCompanionBeingPettedState();
    public WolfCompanionCombatState wolfCompanionCombatState = new WolfCompanionCombatState();
    public WolfIdleState wolfIdleState = new WolfIdleState();

    private void Start()
    {
        currentState = wolfIdleState;
        currentState.EnterState(this);
    }

    private void Update()
    {
        currentState.UpdateState(this);
    }

    public void SwitchState(WolfCompanionDefaultState baseState)
    {
        currentState = baseState;
        baseState.EnterState(this);
    }

    private void OnCollisionEnter(Collision collision)
    {
        currentState.OnCollisionEnter(this, collision);
    }
}

The Abstract State:

using UnityEngine;

public abstract class WolfCompanionDefaultState : StateControllerCompanion
{

   public abstract void EnterState(StateControllerCompanion companion);

    public abstract void UpdateState(StateControllerCompanion companion );

    public abstract void OnCollisionEnter(StateControllerCompanion companion, Collision col);
  
}

The “Entry” concrete state

using UnityEngine;
//using UnityEngine.AI;
public  class WolfIdleState : WolfCompanionDefaultState
{
    //NavMeshAgent navAg;
    public override void EnterState(StateControllerCompanion companion)
    {
        //navAg = GetComponent<NavMeshAgent>();
        Debug.Log("Hello from being idle");
    }

    public override void UpdateState(StateControllerCompanion companion)
    {

    }

    public override void OnCollisionEnter(StateControllerCompanion companion, Collision col)
    {
        //Vector3 colPostOffset = new Vector3(col.transform.position.x - 4, transform.position.y, col.transform.position.z - 5);
        //navAg.SetDestination(colPostOffset);
    }

}

Again, any help with this is appreciated, thanks!

stack overflow always means code execution stuck in some kind of infinite loop. So look for that first.

In this case:

  • public WolfIdleState wolfIdleState = new WolfIdleState();
  • WolfIdleState : WolfCompanionDefaultState// ← big no-no right here
  • so public WolfIdleState wolfIdleState = new WolfIdleState(); again
  • WolfIdleState : WolfCompanionDefaultState
  • ad infinitum…

Do this instead:

using UnityEngine;

public class StateControllerCompanion : MonoBehaviour
{
    ICompanionState currentState;
    [SerializeField] WolfCompanionBeingPettedState wolfCompanionBeingPettedState = new WolfCompanionBeingPettedState();
    [SerializeField] WolfCompanionCombatState wolfCompanionCombatState = new WolfCompanionCombatState();
    [SerializeField] WolfIdleState wolfIdleState = new WolfIdleState();
    void Start()
    {
        currentState = wolfIdleState;
        currentState.EnterState(this);
    }
    void Update()
    {
        currentState.UpdateState(this);
    }
    void OnCollisionEnter(Collision collision)
    {
        currentState.OnCollisionEnter(this, collision);
    }
    public void SwitchState(ICompanionState baseState)
    {
        currentState = baseState;
        baseState.EnterState(this);
    }
}

public interface ICompanionState
{
    void EnterState(StateControllerCompanion companion);
    void UpdateState(StateControllerCompanion companion );
    void OnCollisionEnter(StateControllerCompanion companion, Collision col);
}

[System.Serializable]
public class WolfIdleState : ICompanionState
{
    public void EnterState(StateControllerCompanion companion)
    {
        Debug.Log($"{nameof(WolfIdleState)}::{nameof(EnterState)}()");
    }
    public void UpdateState(StateControllerCompanion companion)
    {
        Debug.Log($"{nameof(WolfIdleState)}::{nameof(UpdateState)}()");
    }
    public void OnCollisionEnter(StateControllerCompanion companion, Collision col)
    {
        Debug.Log($"{nameof(WolfIdleState)}::{nameof(OnCollisionEnter)}()");
    }
}