Unity FSM状态机

状态类:

  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 }
State

状态机类:

  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 }
MachineBehaviour

案例:

 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 }
PlayerIdleState
 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 }
PlayerWalkState
 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 }
PlayerStateMachine

运行截图:

 

posted on 2017-03-20 13:43  爱裸奔的小亮亮  阅读(753)  评论(0编辑  收藏  举报

导航