FSM 浅谈

之前写过一篇关于状态机的,上一篇讲过的我也就不再罗嗦了,不知道欢迎去查看我的上一篇随笔,主要是感觉上次自己封装的还是不行,所以又进行修改了一番!

我本人是个菜鸟,最开始接触状态机的时候,状态机一个可厉害的东西! 因为自己只是知道其大概流程并不是很清楚其内部代码应该怎么去实现!所以之前在学校的时候也是纠结了很长时间(本人比较笨),现在知道了其内部具体是怎么运作的!所以可以自己能够封装出来Simple的小例子,自己封装的可能会有一些BUG,大神路过望指正!

下面先讲状态机的原理,有限状态机主要是解决了游戏中状态的更换,以及省去了更换时的If else或者是Switch的繁杂语句,主要是通过有限状态机内部添加状态和记录状态可以转换的路径(方便装换使用),循环来实现摆脱If else或者是Switch的语句!

下面是详细的代码,里面都有很详细的注释

先看状态类

  1     /// <summary>
  2     /// 状态类
  3     /// </summary>
  4     /// <typeparam name="T"></typeparam>
  5     public class MyState<T>
  6     {
  7         private T myState;
  8         private T fatherState;
  9 
 10         /// <summary>
 11         /// 当前状态
 12         /// </summary>
 13         public T GetNowState
 14         {
 15             get
 16             {
 17                 return myState;
 18             }
 19         }
 20 
 21 
 22         /// <summary>
 23         /// 返回父状态
 24         /// </summary>
 25         public T GetFatherState
 26         {
 27             get
 28             {
 29                 return fatherState;
 30             }
 31             set
 32             {
 33                 if (fatherState == null)
 34                 {
 35                     fatherState = value;
 36                 }
 37                
 38             }
 39         }
 40 
 41 
 42         //自己的状态   父状态
 43         public MyState(T nowestate,T fathertate)
 44         {
 45             myState = nowestate;
 46 
 47             fatherState = fathertate;
 48 
 49         }
 50 
 51 
 52         /// <summary>
 53         /// 转换状态之前触发的事件
 54         /// </summary>
 55         public event FsmEvent DoBeforeEntering;
 56         public void DoEntery()
 57         {
 58             if (DoBeforeEntering != null)
 59             {
 60                 DoBeforeEntering();
 61             }
 62             else
 63             {
 64                 Debug.Log(myState.ToString() + "没有添加事件");
 65             }
 66 
 67         }
 68 
 69 
 70         /// <summary>
 71         /// 转换状态之后触发的事件
 72         /// </summary>
 73         public event FsmEvent DoBeforeLeaving;
 74         public void DoLeave()
 75         {
 76             if (DoBeforeLeaving != null)
 77             {
 78                 DoBeforeLeaving();
 79             }
 80             else
 81             {
 82                 Debug.Log(myState.ToString() + "没有绑定事件");
 83             }
 84 
 85         }
 86 
 87 
 88         /// <summary>
 89         /// Act是表现当前状态行为的函数
 90         /// </summary>
 91         public event FsmEvent Act;
 92         public void DoAction()
 93         {
 94             if (Act != null)
 95             {
 96                 Act();
 97             }
 98             else
 99             {
100                 Debug.Log(myState.ToString() + "没有绑定事件");
101             }
102         }
103     }

然后是记录状态类的fsm类

  1  public class MyFSM<T>
  2     { 
  3         private Dictionary<T,List<MyState<T>>> TranslatList = new Dictionary<T,List<MyState<T>>>();
  4 
  5         private Dictionary<T, MyState<T>> AllState = new Dictionary<T,MyState<T>>();
  6 
  7         private T nowState;
  8 
  9         public void OnStart(T _t)
 10         {
 11             nowState = _t;
 12         }
 13        
 14         /// <summary>
 15         /// 添加装换状态列表
 16         /// </summary>
 17         /// <param name="t"></param>
 18         /// <param name="_myStateList"></param>
 19         public void AddTranslat(T t, List<MyState<T>> _myStateList)
 20         {
 21             if (TranslatList.ContainsKey(t))
 22             {
 23                 TranslatList[t] = _myStateList;
 24                 Debug.Log("重置转换状态");
 25             }
 26             else
 27             {
 28                 TranslatList.Add(t, _myStateList);
 29             }
 30             
 31         }
 32 
 33         /// <summary>
 34         /// 添加单独的装换状态
 35         /// </summary>
 36         /// <param name="t"></param>
 37         /// <param name="_myState"></param>
 38         public void AddTranslat(T t, MyState<T> _myState)
 39         {
 40             if (TranslatList.ContainsKey(t))
 41             {
 42                 List<MyState<T>> _myStateList = new List<MyState<T>>();
 43                 _myStateList = TranslatList[t];
 44                 if (_myStateList.Contains(_myState))
 45                 {
 46                     return;
 47                 }
 48                 else
 49                 {
 50                     _myStateList.Add(_myState);
 51                     TranslatList[t] = _myStateList;
 52                 }
 53             }
 54             else
 55             {
 56                 List<MyState<T>> _myStateList = new List<MyState<T>>();
 57                 _myStateList.Add(_myState);
 58             }
 59         }
 60 
 61         /// <summary>
 62         /// 添加状态
 63         /// </summary>
 64         /// <param name="t"></param>
 65         /// <param name="_state"></param>
 66         public void AddState(T t, MyState<T> _state)
 67         {
 68             if (AllState.ContainsKey(t))
 69             {
 70                 AllState[t] = _state;
 71                 Debug.Log("重置状态");
 72             }
 73             else
 74             {
 75                 AllState.Add(t, _state);
 76             }
 77         }
 78 
 79         /// <summary>
 80         /// 执行
 81         /// </summary>
 82         public void Execution()
 83         { 
 84             AllState[nowState].DoAction();
 85         }
 86 
 87 
 88         /// <summary>
 89         /// 状态转换
 90         /// </summary>
 91         /// <param name="_nextT"></param>
 92         /// <returns></returns>
 93         public bool StateTranslat(T _nextT)
 94         {
 95              //判读是否是同一个状态
 96             //是否可以进入
 97             //执行本状态最后命令
 98             //切换状态
 99             //执行本状态的开始命令
100             if (!nowState.Equals(_nextT))
101             {
102                 if (TranslatList[nowState].Contains(AllState[_nextT]))
103                 //if (nowState.Equals(AllState[_nextT].GetFatherState))
104                 {
105                     MyState<T> state = AllState[nowState];
106                     state.DoEntery();
107                     nowState = _nextT;
108                     state = AllState[nowState];
109                     state.DoEntery();
110                     return true;
111                 }
112                 else
113                 {
114                     return false;
115                 }
116             }
117             else
118             {
119                 return false;
120             }           
121         }
122 
123 
124         /// <summary>
125         /// 关闭FSM
126         /// </summary>
127         public void Close()
128         {
129             TranslatList.Clear();
130             AllState.Clear();
131         }
132 
133     }

以上就是自己封装的fsm,有什么不对的地方欢迎大家指正!

原文地址:https://www.cnblogs.com/mawanli/p/5966080.html