Skip to content

Instantly share code, notes, and snippets.

@gengen1988
Last active October 12, 2022 23:51
Show Gist options
  • Save gengen1988/38f88c6d1aed2b4487a1fa717cc4cc6b to your computer and use it in GitHub Desktop.
Save gengen1988/38f88c6d1aed2b4487a1fa717cc4cc6b to your computer and use it in GitHub Desktop.
A simple state pattern implements for Unity Engine
public class CharacterFSM : FsmBehaviour<CharacterFSM>
{
public float variable = 1f;
protected override State<CharacterFSM> InitState()
{
return new Natural();
}
class Natural : State<CharacterFSM>, ITickable
{
public override void OnEnter()
{
Debug.Log("enter natural");
}
public void Tick(float deltaTime)
{
Debug.Log("nature OnUpdate");
if (Input.anyKey)
{
TransitionTo(new NewState());
}
}
}
class NewState : State<CharacterFSM>, ITickable
{
public void Tick(float deltaTime)
{
Debug.Log($"new OnUpdate: {context.variable}");
}
}
}
public abstract class FsmBehaviour<T> : MonoBehaviour, IStateMachine<T> where T : FsmBehaviour<T>
{
private State<T> _state;
protected virtual void Awake()
{
_state = InitState();
}
protected virtual void FixedUpdate()
{
if (_state is ITickable tickable)
{
tickable.Tick(Time.deltaTime);
}
}
public void TransitionTo(State<T> nextState)
{
nextState.context = this as T;
_state?.OnExit();
_state = nextState;
_state.OnEnter();
}
protected abstract State<T> InitState();
}
public interface ITickable
{
void Tick(float deltaTime);
}
public abstract class State<T> where T : IStateMachine<T>
{
public T context;
protected void TransitionTo(State<T> nextState)
{
context.TransitionTo(nextState);
}
public virtual void OnEnter()
{
}
public virtual void OnExit()
{
}
}
public interface IStateMachine<T> where T : IStateMachine<T>
{
void TransitionTo(State<T> nextState);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment