65 lines
2.0 KiB
C#
65 lines
2.0 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
// This class inherits from MonoBehaviour so it can be attached to a GameObject.
|
|
public class StateMachine : MonoBehaviour
|
|
{
|
|
// A Stack is used to manage states. The top of the stack is the current state.
|
|
// This allows for easily returning to previous states by "popping" the current one.
|
|
public Stack<State> States { get; set; }
|
|
|
|
private void Awake()
|
|
{
|
|
// Initialize the stack when the object is created.
|
|
States = new Stack<State>();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
// Each frame, execute the logic of the current state (if one exists).
|
|
State currentState = GetCurrentState();
|
|
if (currentState != null)
|
|
{
|
|
currentState.Execute();
|
|
}
|
|
}
|
|
|
|
// Pushes a new state onto the stack, making it the current state.
|
|
public void PushState(System.Action active, System.Action onEnter, System.Action onExit)
|
|
{
|
|
// Run the OnExit method of the old state before adding the new one.
|
|
if (GetCurrentState() != null)
|
|
{
|
|
GetCurrentState().OnExit();
|
|
}
|
|
|
|
// Create the new state and push it to the stack.
|
|
State state = new State(active, onEnter, onExit);
|
|
States.Push(state);
|
|
|
|
// Run the OnEnter method for the new current state.
|
|
GetCurrentState().OnEnter();
|
|
}
|
|
|
|
// Removes the current state from the stack, returning to the one below it.
|
|
public void PopState()
|
|
{
|
|
if (GetCurrentState() != null)
|
|
{
|
|
GetCurrentState().OnExit();
|
|
States.Pop();
|
|
// Run the OnEnter of the newly revealed state.
|
|
if (GetCurrentState() != null)
|
|
{
|
|
GetCurrentState().OnEnter();
|
|
}
|
|
}
|
|
}
|
|
|
|
// A helper method to safely get the state at the top of the stack.
|
|
private State GetCurrentState()
|
|
{
|
|
// Uses a ternary operator to return the top state or null if the stack is empty.
|
|
return States.Count > 0 ? States.Peek() : null;
|
|
}
|
|
} |