- Home /
State Machine Question
Hello,
I am pretty inexperienced with coding but I am trying to create a simple state machine. I followed a step-by-step youtube tutorial, but I am having issues.
When I run the scene, I asked the statemachine script to output the current start to the debug log but in my debug log I get both "no current state" and "legs". It seems that because the state is being read as "null" I can't enter a state and update the logic and transition to another state. I'm pretty confused, can anyone let me know what I'm doing wrong??
Thanks so much!
Tutorial: https://www.youtube.com/watch?v=-VkezxxjsSE&t=1288s
StateMachine:
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 
 public class StateMachine : MonoBehaviour
 {
     BaseState  currentState;
 
     void Start()
     {
         currentState = GetInitialState();
         if (currentState != null)
             currentState.Enter();
     }
 
     // Update is called once per frame
     void Update()
     {
         if (currentState != null)
             currentState.UpdateLogic();
     }
     void LateUpdate()
     {
         if (currentState != null)
             currentState.UpdatePhysics();
     }
     public void ChangeState(BaseState newState)
     {
         currentState.Exit();
 
         currentState = newState;
         currentState.Enter();
     }
 
    protected virtual BaseState GetInitialState()
     {
         return null;
     }
 
     private void OnGUI()
     {
         // string content = currentState != null ? currentState.name : ("no current state!");
         //GUILayout.Label($"<color='black'><size=40" > (content) </ size ></ color >);
        
 
         string content = currentState.name;
       
         Debug.Log(content);
         if (currentState == null)
         {
             Debug.Log("no state");
         }
 
       //  GUILayout.Label(content);
         Debug.Log(content);
     }
 }
(Equivalent to the tutorial's MovementSM.cs)
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class TEBody_StateMachine: StateMachine
 {
 
     public  Renderer ren;
     public  Material legColor;
     public  Material PelvisColor;
 
     [HideInInspector]
     public State_Move_Pelvis pelvisState;
     [HideInInspector]
     public State_MoveLegs legsState;
 
   
 
     private void Awake()
     {
         pelvisState = new State_Move_Pelvis(this);
         legsState = new State_MoveLegs(this);
     }
     protected override BaseState GetInitialState()
     {
         
         return legsState;
        
     }
 
 }
 
State 1: Legs equivalent to the tutorial's "idle.cs"
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.InputSystem;
 
 public class State_MoveLegs : BaseState
 {
   
     public State_MoveLegs(TEBody_StateMachine stateMachine) : base("legs", stateMachine) { }
     public override void Enter()
     {
         base.Enter();
     }
 
     public override void UpdateLogic()
     {
         base.UpdateLogic();
 
         // if (GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().ren.material == GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().legColor && Input.GetKey(KeyCode.A))
         if  (Keyboard.current.aKey.isPressed == true)
         
             Debug.Log("A Press");
             stateMachine.ChangeState(((TEBody_StateMachine) stateMachine).pelvisState);
             GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().ren.material = GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().PelvisColor;
             Debug.Log("Change to Pelvis State");
         
     }
 }
State 2 eqivalent to the tutorial's "Moving.cs"
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.InputSystem;
 
 public class State_Move_Pelvis : BaseState
 {
     // Start is called before the first frame update
 
     public State_Move_Pelvis(TEBody_StateMachine stateMachine) : base("pelvis", stateMachine) { }
     public override void Enter()
     {
         base.Enter();
      
     }
 
     public override void UpdateLogic()
     {
         base.UpdateLogic();
 
     
         
         //transition to another state if this input is different from pelvis...
         //if(GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().ren.material == GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().PelvisColor && Input.GetKey(KeyCode.A))
         if (Keyboard.current.bKey.isPressed == true)
         
             Debug.Log("B Press");
             stateMachine.ChangeState(((TEBody_StateMachine)stateMachine).legsState);
             Debug.Log("Change to Leg State");
             GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().ren.material = GameObject.Find("Sphere").GetComponent<TEBody_StateMachine>().legColor;
         
     }
 }
 
Answer by unity_ka6jgzfPPmtNCw · Nov 14, 2021 at 02:52 PM
It seems that because the state is being read as "null"
It's a little hard to see what's wrong as it looks like there are missing scripts (for example, BaseState). I can't see any code where you're changing states, and if you don't, you have a problem as you start with your initial state as null with your Start method call to:
 protected virtual BaseState GetInitialState()
  {
      return null;
  }
I didn't look line by line through it all, but I'd guess that if you set up your initial state, it might work like you want.
 GetInitialState()
 {
   return new StateIdle(); // or whatever state you want to be default
 }
Your answer
 
 
             Follow this Question
Related Questions
How do i use StateMachine logic with my code ? 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                