parent
c52840ccdd
commit
d86b2c44d8
@ -0,0 +1,134 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using ZelleGames.Log;
|
||||
|
||||
namespace ZelleGames.StateMachine
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic abstract state machine with OnEnter and OnExit features
|
||||
/// </summary>
|
||||
public abstract class StateMachine : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Readonly State currently executing
|
||||
/// </summary>
|
||||
public State CurrentState { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Drive the current state if present
|
||||
/// </summary>
|
||||
private void Update()
|
||||
{
|
||||
if (CurrentState != null)
|
||||
{
|
||||
CurrentState.Update(Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drive the current state's FixedUpdate method if state is present
|
||||
/// </summary>
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (CurrentState != null)
|
||||
{
|
||||
CurrentState.FixedUpdate(Time.fixedDeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public facing function to change state based on a transition.
|
||||
/// Relies on an implementation of <see cref="GetNewState(Transition)"/>
|
||||
/// </summary>
|
||||
/// <param name="t">The transition to pass in. Validitiy depends on the implementation of GetNewState</param>
|
||||
public void TransitionState(Transition t)
|
||||
{
|
||||
var newState = GetNewState(t);
|
||||
if (newState != null)
|
||||
{
|
||||
CurrentState?.OnExit();
|
||||
CurrentState = newState;
|
||||
CurrentState.StateMachine = this;
|
||||
CurrentState.OnEnter();
|
||||
} else
|
||||
{
|
||||
Logging.Log(LogLevel.WARN, $"Could not transition from {CurrentState} with {t}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a new state without consideration of the GetNewState function.
|
||||
/// This is sessentially the "goto" of state machine management, use only if absolutely needed.
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public void ForceState(State s)
|
||||
{
|
||||
CurrentState.OnExit();
|
||||
CurrentState = s;
|
||||
CurrentState.OnEnter();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Derived classes should provide an implementation that returns a new <see cref="State"/> depending
|
||||
/// on the Transition passed in.
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <returns>The new state for a valid transition for the current state,
|
||||
/// Null otherwise to maintain current state</returns>
|
||||
protected abstract State GetNewState(Transition t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transitions are passed into the state machine to move from one state to the next.
|
||||
/// </summary>
|
||||
public abstract class Transition
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic object that can contain any information this transition needs to pass into the next state
|
||||
/// </summary>
|
||||
public object Context { get; }
|
||||
|
||||
public Transition() : this(null){}
|
||||
|
||||
public Transition(object ctx)
|
||||
{
|
||||
Context = ctx;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a finite state for a <see cref="StateMachine"/>
|
||||
/// in Unity.
|
||||
/// </summary>
|
||||
public abstract class State
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference to the parent statemachine. Derived classes can cast this reference into their specialized
|
||||
/// class for specific statemachine functionality, or use this reference as is to operate on the base class
|
||||
/// </summary>
|
||||
public StateMachine StateMachine;
|
||||
|
||||
/// <summary>
|
||||
/// Called every frame by the <see cref="StateMachine"/>
|
||||
/// </summary>
|
||||
/// <param name="deltaTime"></param>
|
||||
public abstract void Update(float deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// Called according to the Physics timing configuration by the <see cref="StateMachine"/>
|
||||
/// </summary>
|
||||
/// <param name="fixedDeltaTime"></param>
|
||||
public virtual void FixedUpdate(float fixedDeltaTime) { }
|
||||
|
||||
/// <summary>
|
||||
/// Called on the frame the machine switches to this state
|
||||
/// </summary>
|
||||
public virtual void OnEnter() { }
|
||||
|
||||
/// <summary>
|
||||
/// Called on the last frame before this state is replaced.
|
||||
/// </summary>
|
||||
public virtual void OnExit() { }
|
||||
}
|
||||
}
|
Loading…
Reference in new issue