using UnityEngine; using System.Collections.Generic; [System.Serializable] public class StateFunc { public delegate void EnterFunc(object param); public delegate void ExitFunc(); public delegate void UpdateFunc(float dt); public EnterFunc enterFunc; public ExitFunc exitFunc; public UpdateFunc updateFunc; } [System.Serializable()] public class FsmManager<T> where T : struct { /// <summary> /// 之前的状态 /// </summary> [SerializeField] protected T _prevState; /// <summary> /// 当前的状态 /// </summary> [SerializeField] protected T _currState; [SerializeField] public float stateTimer = 0; public T CurrState { get { return _currState; } } protected Dictionary<T, StateFunc> _stateFuncs = new Dictionary<T, StateFunc>(); /// <summary> /// 注册状态 /// </summary> /// <param name="state"></param> /// <param name="enter"></param> /// <param name="update"></param> /// <param name="exit"></param> public void RegistState(T state,StateFunc.EnterFunc enter,StateFunc.UpdateFunc update,StateFunc.ExitFunc exit) { StateFunc func = new StateFunc { enterFunc = enter, updateFunc = update, exitFunc = exit }; _stateFuncs.Add(state, func); Debug.Log("State:" + state); } /// <summary> /// 更新状态 /// </summary> /// <param name="dt"></param> public void UpdateState(float dt) { if(_stateFuncs.ContainsKey(_currState)&&(_stateFuncs[_currState].updateFunc != null)) { _stateFuncs[_currState].updateFunc(dt); } } /// <summary> /// 设置状态 /// </summary> /// <param name="state"></param> /// <param name="param"></param> public void SetState(T state,object param = null) { if (_stateFuncs.Equals(state)) return; T curState = _currState; _prevState = curState; _currState = state; if (_stateFuncs.ContainsKey(curState) && (_stateFuncs[curState].exitFunc) != null) { _stateFuncs[curState].exitFunc(); } if(_stateFuncs.ContainsKey(_currState) &&( _stateFuncs[_currState].enterFunc)!=null) { _stateFuncs[_currState].enterFunc(param); } stateTimer = 0; } /// <summary> /// 是否有状态 /// </summary> /// <param name="state"></param> /// <returns></returns> public bool HasState(T state) { return _stateFuncs.ContainsKey(state); } }
using System; using UnityEngine; public class TFsm : MonoBehaviour { public enum EnemyState { Idle, Attack, Run, Die } FsmManager<EnemyState> enemyState = new FsmManager<EnemyState>(); void Start() { enemyState.RegistState(EnemyState.Idle, OnIdleEnter, OnIdleUpdate, OnIdleExit); enemyState.RegistState(EnemyState.Run, OnRunEnter, OnRunUpdate, OnRunExit); enemyState.RegistState(EnemyState.Attack, OnAttackEnter, OnAttackUpdate, OnAttackExit); enemyState.RegistState(EnemyState.Die, OnDieEnter, OnDieUpdate, OnDieExit); enemyState.SetState(EnemyState.Idle); } private void OnDieExit() { Debug.Log("退出死亡"); } private void OnDieUpdate(float dt) { Debug.Log("更新死亡"); } private void OnDieEnter(object param) { Debug.Log("进入死亡"); } private void OnAttackExit() { Debug.Log("退出攻击"); } private void OnAttackUpdate(float dt) { Debug.Log("更新攻击"); } private void OnAttackEnter(object param) { Debug.Log("进入攻击"); } private void OnRunExit() { Debug.Log("退出奔跑"); } private void OnRunUpdate(float dt) { Debug.Log("更新奔跑"); } private void OnRunEnter(object param) { Debug.Log("进入奔跑"); } private void OnIdleExit() { Debug.Log("退出Idle"); } private void OnIdleUpdate(float dt) { Debug.Log("更新Idle"); } private void OnIdleEnter(object param) { Debug.Log("进入Idle"); } void Update() { float dt = Time.deltaTime; enemyState.UpdateState(dt); if (Input.GetKeyDown(KeyCode.Q)) { enemyState.SetState(EnemyState.Idle); } if (Input.GetKeyDown(KeyCode.W)) { enemyState.SetState(EnemyState.Run); } if (Input.GetKeyDown(KeyCode.E)) { enemyState.SetState(EnemyState.Attack); } if (Input.GetKeyDown(KeyCode.R)) { enemyState.SetState(EnemyState.Die); } } }