状态基类:先布置好委托,继承的子类可以通过回调函数添加事件,在Enterstate这些虚函数里面写了回调,重写的时候也要触发一下
1、FSMTriggerID:条件ID枚举
1 2 3 4 5 6 7 8 9 10 11
| namespace CharacterControlSystem.CharacterFSM { public enum FSMTriggerID { JumpToIdleDetection, MoveToIdleDetection, IdleToMoveDetection, IdleToJumpDetection, } }
|
2、FSMStateID:状态ID枚举
1 2 3 4 5 6 7 8 9 10
| namespace CharacterControlSystem.CharacterFSM { public enum FSMStateID { Default, Idle, Run, Jump, } }
|
3、FSMTrigger:条件基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| using System; using UnityEngine;
namespace CharacterControlSystem.CharacterFSM { public abstract class FSMTrigger { public FSMTriggerID TriggerId { get; set; }
public FSMTrigger() { InitId(); } protected abstract void InitId(); public abstract bool HandleTrigger(GameObject thisGameObject); } }
|
4、FSMState:状态基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| using System; using System.Collections.Generic; using UnityEngine;
namespace CharacterControlSystem.CharacterFSM { public abstract class FSMState { public FSMStateID StateId { get; set; } private Dictionary<FSMTriggerID, FSMStateID> _map; private List<FSMTrigger> _triggers; private Action enterStateHandler; private Action stayStateHandler; private Action exitStateHandler; protected GameObject thisGameObject; public FSMState(GameObject thisGameObject) { this.thisGameObject = thisGameObject; _map = new Dictionary<FSMTriggerID, FSMStateID>(); _triggers = new List<FSMTrigger>(); InitState(); } protected abstract void InitState(); public void AddMap(FSMTriggerID triggerId, FSMStateID stateId) { _map.Add(triggerId, stateId); CreateTrigger(triggerId); } private void CreateTrigger(FSMTriggerID triggerId) { Type triggerType = Type.GetType("CharacterControlSystem.CharacterFSM.SubFSM.Trigger." +triggerId+ "Trigger"); if (triggerType != null) { FSMTrigger trigger = Activator.CreateInstance(triggerType) as FSMTrigger; _triggers.Add(trigger); } } public void Reason(FSMBase fsmBase) { for (int i = 0; i < _triggers.Count; i++) { if (_triggers[i].HandleTrigger(fsmBase.gameObject)) { fsmBase.ChangeState(_map[_triggers[i].TriggerId]); return; } } } public void AddEnterStateListener(Action func) { enterStateHandler += func; } public void AddStayStateListener(Action func) { stayStateHandler += func; } public void AddExitStateListener(Action func) { exitStateHandler += func; } public virtual void EnterState() { enterStateHandler?.Invoke(); } public virtual void StayState() { stayStateHandler?.Invoke(); } public virtual void ExitState() { exitStateHandler?.Invoke(); } } }
|
5、FSMBase:状态机基类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| using System.Collections.Generic; using CsharpBaseModule.PublicMono; using UnityEngine;
namespace CharacterControlSystem.CharacterFSM { public abstract class FSMBase : MonoBehaviour { protected Dictionary<FSMStateID,FSMState> _states; [Tooltip("请选择默认状态")] public FSMStateID defaultStateId; protected FSMState _defaultState; public FSMState currentState; protected virtual void Awake() { ConfigFSM(); InitDefaultState(); MonoManager.GetInstance.AddUpdateListener(BaseUpdate); } protected virtual void ConfigFSM() { _states = new Dictionary<FSMStateID, FSMState>(); } protected virtual void InitDefaultState() { _defaultState = _states[defaultStateId]; currentState = _defaultState; currentState.EnterState(); } protected virtual void BaseUpdate() { currentState.Reason(this); currentState.StayState(); } public void ChangeState(FSMStateID stateId) { currentState.ExitState(); currentState = stateId == FSMStateID.Default ? _defaultState : _states[stateId]; currentState.EnterState(); } protected FSMState AddState(FSMStateID stateId, FSMState state) { _states.Add(stateId, state); return state; } protected FSMState FindState(FSMStateID stateId) { if (_states.ContainsKey(stateId)) { return _states[stateId]; }
return null; } } }
|
案例
总结:
1、添加好状态枚举和条件枚举
2、条件需要添加好InitId和HandleTrigger
3、状态需要添加好InitId和AddMap
转化
- 定义FSMTriggerID和FSMStateID枚举:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public enum PlayerFSMTriggerID { Walk, Run, Stop, }
public enum PlayerFSMStateID { Idle, Walking, Running, }
|
- 实现FSM触发器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| namespace CharacterControlSystem.CharacterFSM.SubFSM.Trigger { public class WalkTrigger : FSMTrigger { protected override void InitId() { TriggerId = PlayerFSMTriggerID.Walk; }
public override bool HandleTrigger(GameObject thisGameObject) { return Input.GetKey(KeyCode.W); } }
public class RunTrigger : FSMTrigger { protected override void InitId() { TriggerId = PlayerFSMTriggerID.Run; }
public override bool HandleTrigger(GameObject thisGameObject) { return Input.GetKey(KeyCode.LeftShift); } }
public class StopTrigger : FSMTrigger { protected override void InitId() { TriggerId = PlayerFSMTriggerID.Stop; }
public override bool HandleTrigger(GameObject thisGameObject) { return !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.LeftShift); } } }
|
- 实现FSM状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| namespace CharacterControlSystem.CharacterFSM.SubFSM { public class IdleState : FSMState { protected override void InitState() { StateId = PlayerFSMStateID.Idle; AddMap(PlayerFSMTriggerID.Walk, PlayerFSMStateID.Walking); AddMap(PlayerFSMTriggerID.Run, PlayerFSMStateID.Running); } }
public class WalkingState : FSMState { protected override void InitState() { StateId = PlayerFSMStateID.Walking; AddMap(PlayerFSMTriggerID.Run, PlayerFSMStateID.Running); AddMap(PlayerFSMTriggerID.Stop, PlayerFSMStateID.Idle); } }
public class RunningState : FSMState { protected override void InitState() { StateId = PlayerFSMStateID.Running; AddMap(PlayerFSMTriggerID.Stop, PlayerFSMStateID.Idle); } } }
|
- 实现PlayerFSM:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| namespace CharacterControlSystem.CharacterFSM { public class PlayerFSM : FSMBase { protected override void ConfigFSM() { var idleState = AddState(PlayerFSMStateID.Idle, new IdleState()); var walkingState = AddState(PlayerFSMStateID.Walking, new WalkingState()); var runningState = AddState(PlayerFSMStateID.Running, new RunningState());
defaultStateId = PlayerFSMStateID.Idle; } } }
|