状态类:
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using UnityEngine; 5 6 public class State 7 { 8 /// <summary> 9 /// 存储状态能够转换的列表 10 /// </summary> 11 protected List<Type> list = new List<Type>(); 12 13 /// <summary> 14 /// 添加可转换状态到列表中存储 15 /// </summary> 16 /// <typeparam name="T"></typeparam> 17 public void AddTransition<T>() where T :State 18 { 19 if (list.Contains(typeof(T))) 20 { 21 Debug.LogError("转换状态:" + typeof(T) + "已经有了对应的状态"); 22 return; 23 } 24 list.Add(typeof(T)); 25 } 26 27 /// <summary> 28 /// 从列表中删除某个可转换的状态 29 /// </summary> 30 /// <typeparam name="T"></typeparam> 31 public void DeleteTransition<T>() where T : State 32 { 33 if (list.Contains(typeof(T)) == false) 34 { 35 Debug.LogWarning("转换条件:" + typeof(T) + "没有存在在map字典内!"); 36 return; 37 } 38 list.Remove(typeof(T)); 39 } 40 41 /// <summary> 42 /// 判断某个类型是否可转换 43 /// </summary> 44 /// <param name="type"></param> 45 /// <returns></returns> 46 public bool IsTransition(Type type) 47 { 48 if (list.Contains(type)) 49 { 50 return true; 51 } 52 return false; 53 } 54 55 /// <summary> 56 /// 状态是否启用 57 /// </summary> 58 public bool isActive 59 { 60 get { return machine.IsCurrentState(GetType()); } 61 } 62 63 /// <summary> 64 /// 获取控制当前状态的状态机 65 /// </summary> 66 public MachineBehaviour machine 67 { 68 get; 69 internal set; 70 } 71 72 /// <summary> 73 /// 状态初始化 74 /// </summary> 75 public virtual void Initialize() 76 { 77 78 } 79 /// <summary> 80 /// 进入状态时执行 81 /// </summary> 82 public virtual void Enter() 83 { 84 85 } 86 /// <summary> 87 /// 状态Update时执行 88 /// </summary> 89 public virtual void Execute() 90 { 91 92 } 93 /// <summary> 94 /// 退出状态时执行 95 /// </summary> 96 public virtual void Exit() 97 { 98 99 } 100 /// <summary> 101 /// 状态FixedUpdate时执行 102 /// </summary> 103 public virtual void FixedExecute() 104 { 105 106 } 107 /// <summary> 108 /// 状态LateUpdate时执行 109 /// </summary> 110 public virtual void LateExecute() 111 { 112 113 } 114 115 public virtual void OnCollisionEnter(Collision collision) 116 { 117 118 } 119 public virtual void OnCollisionExit(Collision collision) 120 { 121 122 } 123 public virtual void OnCollisionStay(Collision collision) 124 { 125 126 } 127 public virtual void OnTriggerEnter(Collider collider) 128 { 129 130 } 131 public virtual void OnTriggerExit(Collider collider) 132 { 133 134 } 135 public virtual void OnTriggerStay(Collider collider) 136 { 137 138 } 139 }
状态机类:
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using UnityEngine; 5 6 public abstract class MachineBehaviour : MonoBehaviour 7 { 8 /// <summary> 9 /// 状态机的当前状态 10 /// </summary> 11 protected State currentState { get; set; } 12 13 /// <summary> 14 /// 状态机存储的状态列表 15 /// </summary> 16 protected Dictionary<Type, State> states = new Dictionary<Type, State>(); 17 18 /// <summary> 19 /// 对状态机添加一些状态 20 /// </summary> 21 public abstract void AddStates(); 22 23 /// <summary> 24 /// 对状态机的初始化操作 25 /// </summary> 26 public virtual void Initialize() 27 { 28 AddStates(); 29 30 if (currentState == null) 31 { 32 throw new System.Exception("状态机:" + name + "的currentState没有设置,请通过SetCurrentState()函数设置!"); 33 } 34 35 // 对状态机里的每个状态进行初始化 36 foreach (KeyValuePair<Type, State> pair in states) 37 { 38 pair.Value.Initialize(); 39 } 40 41 currentState.Enter(); 42 } 43 44 /// <summary> 45 /// 添加一个状态到状态机 46 /// </summary> 47 /// <typeparam name="T"></typeparam> 48 public void AddState<T>() where T : State, new() 49 { 50 if (!ContainsState<T>()) 51 { 52 State item = new T(); 53 item.machine = this; 54 55 states.Add(typeof(T), item); 56 } 57 } 58 59 /// <summary> 60 /// 转换状态 61 /// </summary> 62 /// <typeparam name="T"></typeparam> 63 public void ChangeState<T>() where T : State 64 { 65 if (states[typeof(T)] == null) 66 { 67 throw new System.Exception("状态机查找不到状态:" + typeof(T).Name); 68 } 69 if (!currentState.IsTransition(typeof(T))) 70 { 71 throw new System.Exception("状态机查找不到状态转换条件:" + typeof(T).Name); 72 } 73 currentState.Exit(); 74 currentState = states[typeof(T)]; 75 currentState.Enter(); 76 } 77 78 /// <summary> 79 /// 检查状态机是否包含某个状态 80 /// </summary> 81 /// <typeparam name="T"></typeparam> 82 /// <returns></returns> 83 public bool ContainsState<T>() where T : State 84 { 85 return states.ContainsKey(typeof(T)); 86 } 87 88 /// <summary> 89 /// 获得状态机的当前状态 90 /// </summary> 91 /// <typeparam name="T"></typeparam> 92 /// <returns></returns> 93 public T CurrentState<T>() where T : State 94 { 95 return (T)currentState; 96 } 97 98 /// <summary> 99 /// 获取状态机某个状态 100 /// </summary> 101 /// <typeparam name="T"></typeparam> 102 /// <returns></returns> 103 public T GetState<T>() where T : State 104 { 105 if (states[typeof(T)] == null) 106 { 107 throw new System.Exception("状态机:" + name + "查找不到状态:" + typeof(T).Name); 108 } 109 return (T)states[typeof(T)]; 110 } 111 112 /// <summary> 113 /// 判断某个状态是否为状态机当前状态 114 /// </summary> 115 /// <typeparam name="T"></typeparam> 116 /// <returns></returns> 117 public bool IsCurrentState<T>() where T : State 118 { 119 return (currentState.GetType() == typeof(T)) ? true : false; 120 } 121 public bool IsCurrentState(System.Type T) { return (currentState.GetType() == T) ? true : false; } 122 123 124 /// <summary> 125 /// 移除状态机所有状态 126 /// </summary> 127 public void RemoveAllStates() 128 { 129 states.Clear(); 130 } 131 132 /// <summary> 133 /// 移除状态机某个状态 134 /// </summary> 135 /// <typeparam name="T"></typeparam> 136 public void RemoveState<T>() where T : State 137 { 138 states.Remove(typeof(T)); 139 } 140 141 /// <summary> 142 /// 设置状态机当前状态 143 /// </summary> 144 /// <typeparam name="T"></typeparam> 145 public void SetCurrentState<T>() where T : State 146 { 147 currentState = states[typeof(T)]; 148 } 149 150 public virtual void Start() 151 { 152 Initialize(); 153 } 154 public virtual void Update() 155 { 156 currentState.Execute(); 157 } 158 public virtual void FixedUpdate() 159 { 160 currentState.FixedExecute(); 161 } 162 public virtual void LateUpdate() 163 { 164 currentState.LateExecute(); 165 } 166 167 // 状态机传递一些特殊的操作给状态 168 public void OnCollisionEnter(Collision collision) 169 { 170 currentState.OnCollisionEnter(collision); 171 } 172 public void OnCollisionExit(Collision collision) 173 { 174 currentState.OnCollisionExit(collision); 175 176 } 177 public void OnCollisionStay(Collision collision) 178 { 179 currentState.OnCollisionStay(collision); 180 } 181 public void OnTriggerEnter(Collider collider) 182 { 183 currentState.OnTriggerEnter(collider); 184 } 185 public void OnTriggerExit(Collider collider) 186 { 187 currentState.OnTriggerExit(collider); 188 } 189 public void OnTriggerStay(Collider collider) 190 { 191 currentState.OnTriggerStay(collider); 192 } 193 194 195 }
案例:
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class PlayerIdleState : State 6 { 7 private bool isExecute = false; 8 private PlayerStateMachine playerMachine { get { return (PlayerStateMachine)machine; } } 9 10 public override void Initialize() 11 { 12 AddTransition<PlayerWalkState>(); 13 } 14 15 public override void Enter() 16 { 17 Debug.Log("PlayerIdleState Enter"); 18 isExecute = false; 19 } 20 21 public override void Execute() 22 { 23 if (!isExecute) 24 { 25 Debug.Log("PlayerIdleState Execute"); 26 isExecute = true; 27 } 28 if (Input.GetKeyDown(KeyCode.S)) 29 { 30 Debug.Log("转到状态PlayerWalkState"); 31 playerMachine.ChangeState<PlayerWalkState>(); 32 } 33 } 34 35 public override void Exit() 36 { 37 Debug.Log("PlayerIdleState Exit"); 38 } 39 }
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 public class PlayerWalkState : State 6 { 7 private bool isExecute = false; 8 private PlayerStateMachine playerMachine { get { return (PlayerStateMachine)machine; } } 9 10 public override void Initialize() 11 { 12 AddTransition<PlayerIdleState>(); 13 } 14 15 public override void Enter() 16 { 17 Debug.Log("PlayerWalkState Enter"); 18 isExecute = false; 19 } 20 21 public override void Execute() 22 { 23 if (!isExecute) 24 { 25 Debug.Log("PlayerWalkState Execute"); 26 isExecute = true; 27 } 28 if (Input.GetKeyDown(KeyCode.S)) 29 { 30 Debug.Log("转到状态PlayerIdleState"); 31 playerMachine.ChangeState<PlayerIdleState>(); 32 } 33 } 34 35 public override void Exit() 36 { 37 Debug.Log("PlayerWalkState Exit"); 38 } 39 }
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using UnityEngine; 5 6 public class PlayerStateMachine : MachineBehaviour { 7 8 public override void AddStates() 9 { 10 AddState<PlayerIdleState>(); 11 AddState<PlayerWalkState>(); 12 13 SetCurrentState<PlayerIdleState>(); 14 } 15 }
运行截图: