- 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