namespace FSM
{
public class State
{
//指明当前状态机被哪个状态机所管理
public StateMachine stateMachine;
//三种状态
public virtual void EnterState()
{
}
public virtual void UpadateState()
{
}
public virtual void ExitState()
{
}
}
//吃饭状态
public class EatState : State
{
public override void EnterState()
{
Debug.Log("饭前洗手");
}
public override void UpadateState()
{
Debug.Log("吃饭中");
if (Input.GetKeyDown(KeyCode.A))
{
stateMachine.ChangeState("Study");
}
}
public override void ExitState()
{
Debug.Log("饭后甜点");
}
}
//睡觉状态
public class SleepState : State
{
public override void EnterState()
{
Debug.Log("睡前洗漱");
}
public override void UpadateState()
{
Debug.Log("睡觉中zzzZZZZ");
if (Input.GetKeyDown(KeyCode.A))
{
stateMachine.ChangeState("Eat");
}
}
public override void ExitState()
{
Debug.Log("睡醒了");
}
}
//学习状态
public class StudyState : State
{
public override void EnterState()
{
Debug.Log("学前准备");
}
public override void UpadateState()
{
Debug.Log("学习中");
if (Input.GetKeyDown(KeyCode.A))
{
stateMachine.ChangeState("Sleep");
}
}
public override void ExitState()
{
Debug.Log("下班");
}
}
public class StateMachine
{
//自定义一个key值即状态名 对应一个行为状态
private Dictionary<string,State> _stateDic = new Dictionary<string, State>();
private State _currentState;
//注册 对应新动画系统中 把动画剪辑拖入到窗口中
public void Register(string key, State state)
{
state.stateMachine = this;
_stateDic.Add(key, state);
}
//设置默认 对应新动画系统中 右键选择起始状态
public void SetDefault(string stateName)
{
if (_stateDic.ContainsKey(stateName))
{
_currentState = _stateDic[stateName];
_currentState.EnterState();
}
}
//改变 对应新动画系统中 状态之间的连线 处理状态之间的切换
public void ChangeState(string stateName)
{
if (_currentState != null)
{
_currentState.ExitState();
}
if (_stateDic.ContainsKey(stateName))
{
_currentState = _stateDic[stateName];
_currentState.EnterState();
}
}
//状态机执行
public void DoWork()
{
if (_currentState != null)
{
_currentState.UpadateState();
}
}
}
}
状态机的添加和调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FSM;
public class TestFSM : MonoBehaviour {
StateMachine stateMachine;
// Use this for initialization
void Start () {
stateMachine = new StateMachine();
stateMachine.Register("Sleep", new FSM.SleepState());
stateMachine.Register("Eat", new FSM.EatState());
stateMachine.Register("Study", new FSM.StudyState());
stateMachine.SetDefault("Sleep");
}
// Update is called once per frame
void Update () {
stateMachine.DoWork();
}
}