分享一个unity3d 有限状态机 例子来供大家学习、参考和交流,因为我们一般在游戏中都会这样使用状态机,代码如下:。

  1. enum State_Type
  2. {
  3. GameMenu,
  4. GameLoading,
  5. GameLogic,
  6. GameOver,
  7. }
  8.  
  9. void Update()
  10. {
  11.      
  12. switch(currentstate)
  13.      
  14. {
  15.     
  16. case State_Type. GameMenu:
  17.         
  18. if( 按了开始按钮 )
  19.         
  20. {
  21.             
  22. currentstate=State_Type. GameLoading;
  23.         
  24. }
  25.         
  26. if( 按了成就 )
  27.         
  28. {
  29.             
  30. currentstate=State_Type……..;
  31.         
  32. }
  33.         
  34. if(按了高分榜)
  35.         
  36. {
  37.             
  38. currentstate=State_Type……..;
  39.         
  40. }
  41.  
  42.  
  43.     
  44. break; 
  45.              
  46. case State_Type. GameLoading:
  47.         
  48. if( 加载游戏完成 )
  49.         
  50. {
  51.             
  52. currentstate=State_Type. GameLogic;
  53.         
  54. }
  55.     
  56. break; 
  57.              
  58. case State_Type. GameLogic:
  59.         
  60. if( 死了 )
  61.         
  62. {
  63.             
  64. currentstate=State_Type. GameOver;
  65.         
  66. }
  67.     
  68. break; 
  69.              
  70. case State_Type. GameOver:
  71.             
  72. currentstate=State_Type. GameMenu;
  73.     
  74. break; 
  75.     
  76. }
  77. }
 

这样写没有什么问题。不过当状态多的时候确实很头疼。

有一种方法可以解决这样的问题(有限状态机FSM)

下面是一个例子 

两个实体
ActorOne
ActorTwo 

第一个实体ActorOne
  1. using UnityEngine;
  2. using System.Collections;
  3. public class ActorOne  : BaseGameEntity {
  4.     
  5. //有限状态机
  6.     
  7. StateMachine<ActorOne> m_pStateMachine;
  8.     
  9. void Start () {
  10.         
  11. //设置实体的id必须唯一
  12.         
  13. SetID((int)EntityID.m_ActorOne);
  14.  
  15.  
  16.         
  17. //注册
  18.         
  19. m_pStateMachine = new StateMachine<ActorOne>(this);
  20.         
  21. /* 
  22.             
  23. 一个状态分为三个阶段
  24.                    
  25. Enter()       //进入
  26.                    
  27. Execute() //执行
  28.                    
  29. Exit()           //离开
  30.  
  31.  
  32.             
  33. 当m_pStateMachine.SetCurrentState(ActorOne_StateOne .Instance());
  34.  
  35.  
  36.             
  37. 会先执行ActorOne_StateOne 的Enter()方法,
  38.             
  39. 然后执行ActorOne_StateOne 的Execute()方法, Execute方法会一直执行直到切换状态
  40.  
  41.  
  42.             
  43. 当在ActorOne_StateOne(Enter(), Execute())中调用Entity.GetFSM().ChangeState(ActorOne_StateTwo.Instance());
  44.  
  45.  
  46.             
  47. 会先执行ActorOne_StateOne 的Exit();
  48.             
  49. 然后执行ActorOne_StateTwo的Enter()方法,
  50.             
  51. 然后执行ActorOne_StateTwo的Execute()方法,
  52.  
  53.  
  54.  
  55.  
  56.         
  57. */
  58.  
  59.  
  60.  
  61.  
  62.         
  63. //设置当前的状态为ActorOne_StateOne
  64.         
  65. m_pStateMachine.SetCurrentState(ActorOne_StateOne .Instance());    
  66.         
  67. //设置全局的状态
  68.         
  69. m_pStateMachine.SetGlobalStateState(ActorOne_GloballState .Instance());
  70.  
  71.  
  72.  
  73.  
  74.         
  75. //实体注册到实体管理器中
  76.         
  77. EntityManager.Instance().RegisterEntity(this);
  78.     
  79. }
  80.  
  81.  
  82.     
  83. void Update ()
  84.     
  85. {    
  86.         
  87. //状态机update
  88.         
  89. m_pStateMachine.SMUpdate();
  90.     
  91. }
  92.  
  93.  
  94.  
  95.  
  96.     
  97. public StateMachine<ActorOne> GetFSM ()
  98.     
  99. {
  100.         
  101. //获得状态机
  102.         
  103. return m_pStateMachine;
  104.     
  105. }
  106.  
  107.  
  108.     
  109. public override bool HandleMessage (Telegram telegram)
  110.     
  111. {
  112.         
  113. //解析消息
  114.         
  115. return     m_pStateMachine.HandleMessage(telegram);
  116.     
  117. }
  118. }
 

第2个实体ActorTwo
  1. using UnityEngine;
  2. using System.Collections;
  3. public class ActorTwo  : BaseGameEntity {
  4.  
  5.  
  6.     
  7. StateMachine<ActorTwo> m_pStateMachine;
  8.  
  9.  
  10.     
  11. public Transform TwoTransform;
  12.  
  13.  
  14.     
  15. // Use this for initialization
  16.     
  17. void Start () {

  18.         
  19. // set id 
  20.         
  21. SetID((int)EntityID.m_ActorTwo);

  22.         
  23. m_pStateMachine = new StateMachine<ActorTwo>(this)
  24.         
  25. m_pStateMachine.SetCurrentState(ActorTwo_StateOne.Instance());    

  26.         
  27. m_pStateMachine.SetGlobalStateState(ActorTwo_GloballState.Instance());
  28.         
  29. EntityManager.Instance().RegisterEntity(this);
  30.     
  31. }

  32.     
  33. void Update ()
  34.     
  35. {    
  36.         
  37. m_pStateMachine.SMUpdate();
  38.     
  39. }
  40.  
  41.  
  42.  
  43.  
  44.     
  45. public StateMachine<ActorTwo> GetFSM ()
  46.     
  47. {
  48.         
  49. return m_pStateMachine;
  50.     
  51. }
  52.  
  53.  
  54.     
  55. public override bool HandleMessage (Telegram telegram)
  56.     
  57. {
  58.         
  59. return     m_pStateMachine.HandleMessage(telegram);
  60.     
  61. }
  62. }
 

ActorOneState 第一个实体的状态

  1. using UnityEngine;
  2. using System.Collections; 
  3. /*
  4. 状态分为两种
  5. 1全局状态 一般情况下会一直执行 可以负责调度
  6. 2普通状态 也就是上面的GameMenu,GameLoading,GameLogic,GameOver,
  7. */
  8. //全局状态
  9. public class ActorOne_GloballState :State<ActorOne >
  10. {
  11.     
  12. private static ActorOne_GloballState instance;
  13.     
  14. public static ActorOne_GloballState Instance ()
  15.     
  16. {
  17.         
  18. if (instance == null)
  19.             
  20. instance = new ActorOne_GloballState ();
  21.  
  22.  
  23.         
  24. return instance;
  25.     
  26. }
  27.  
  28.  
  29.     
  30. //当状态被调用是执行一次
  31.     
  32. public override void Enter (ActorOne Entity)
  33.     
  34. {
  35.         
  36. //base.Enter (Entity);
  37.     
  38. }
  39.  
  40.  
  41.  
  42.  
  43.     
  44. //相当于update方法
  45.     
  46. public override void Execute (ActorOne Entity)
  47.     
  48. {
  49.         
  50. //base.Execute (Entity);    
  51.     
  52. }
  53.  
  54.  
  55.     
  56. //状态退出是被调用
  57.     
  58. public override void Exit (ActorOne Entity)
  59.     
  60. {
  61.         
  62. //base.Exit (Entity);
  63.     
  64. }
  65.  
  66.  
  67.     
  68. //接收消息
  69.     
  70. public override bool OnMessage (ActorOne Entity, Telegram telegram)
  71.     
  72. {
  73.         
  74. return false;
  75.     
  76. }
  77. }
  78.  
  79.  
  80.  
  81.  
  82. public class ActorOne_StateOne : State<ActorOne>
  83. {
  84.     
  85. private static ActorOne_StateOne instance;
  86.     
  87. public static ActorOne_StateOne Instance ()
  88.     
  89. {
  90.         
  91. if (instance == null)
  92.             
  93. instance = new ActorOne_StateOne ();
  94.  
  95.  
  96.         
  97. return instance;
  98.     
  99. }
  100.  
  101.  
  102.     
  103. public override void Enter (ActorOne Entity)
  104.     
  105. {
  106.         
  107. //base.Enter (Entity);
  108.     
  109. }
  110.  
  111.  
  112.  
  113.  
  114.     
  115. public override void Execute (ActorOne Entity)
  116.     
  117. {
  118.         
  119. /*
  120.         
  121. 调用实体的GetFSM()获得状态机器
  122.         
  123. 在调用状态机的ChangeState(ActorOne_StateTwo.Instance())
  124.         
  125. 改变状态
  126.         
  127. 这里是从当前状态ActorOne_StateOne切换到ActorOne_StateTwo状态;
  128.         
  129. */
  130.         
  131. Entity.GetFSM().ChangeState(ActorOne_StateTwo.Instance());
  132.         
  133. //base.Execute (Entity);
  134.     
  135. }
  136.  

  137.     
  138. public override void Exit (ActorOne Entity)
  139.     
  140. {
  141.         
  142. //base.Exit (Entity);
  143.     
  144. }
  145.  

  146.     
  147. public override bool OnMessage (ActorOne Entity, Telegram telegram)
  148.     
  149. {
  150.         
  151. return false;
  152.     
  153. }
  154. }
  155.  

  156. public class ActorOne_StateTwo : State<ActorOne>
  157. {
  158.     
  159. private static ActorOne_StateTwo instance;
  160.     
  161. public static ActorOne_StateTwo Instance ()
  162.     
  163. {
  164.         
  165. if (instance == null)
  166.             
  167. instance = new ActorOne_StateTwo ();
  168.  
  169.     
  170. return instance;
  171.     
  172. }
  173.  
  174.  
  175.     
  176. public override void Enter (ActorOne Entity)
  177.     
  178. {
  179.         
  180. /*
  181.             
  182. MessageDispatcher.Instance().DispatchMessage();用于在实体间传送消息
  183.  
  184.          
  185. 下面代码的意思就是
  186.             
  187. 发送消息给ActorTwo,延迟5秒发送,消息的类型msg_oneMessage
  188.         
  189. */
  190.         
  191. MessageDispatcher.Instance().DispatchMessage(
  192.                 
  193. 5f, // delay 消息的延迟时间
  194.                                 
  195. Entity.ID(),        // sender 发送者
  196.                                
  197. (int)EntityID.m_ActorTwo,            // receiver 接收者
  198.                                
  199. (int)message_type.msg_oneMessage,    //message
  200.                                 
  201. Entity);  //附加信息
  202.         
  203. //base.Enter (Entity);
  204.     
  205. }
  206.  
  207.   
  208. public override void Execute (ActorOne Entity)
  209.     
  210. {
  211.         
  212. //base.Execute (Entity);
  213.     
  214. }
  215.  
  216.  
  217. public override void Exit (ActorOne Entity)
  218.     
  219. {
  220.         
  221. //base.Exit (Entity);
  222.     
  223. }
  224.  
  225.   
  226. public override bool OnMessage (ActorOne Entity, Telegram telegram)
  227.     
  228. {
  229.         
  230. /*
  231.             
  232. 接收ActorTwo发送过来的消息(message_type.msg_twoMessage)
  233.         
  234. */
  235.         
  236. if(telegram.Msg == (int)message_type.msg_twoMessage)
  237.         
  238. {
  239.             
  240. /*
  241.                 
  242. 接收成功
  243.             
  244. */
  245.             
  246. return true;
  247.         
  248. }
  249.  
  250.  
  251.         
  252. return false;
  253.     
  254. }
  255. }
  256.  

  257. ActorTwo 第2个实体的具体状态
  258. using UnityEngine;
  259. using System.Collections;
  260.  
  261.  
  262.  
  263.  
  264. public class ActorTwo_GloballState : State<ActorTwo>
  265. {
  266.     
  267. private static ActorTwo_GloballState instance;
  268.     
  269. public static ActorTwo_GloballState Instance ()
  270.     
  271. {
  272.         
  273. if (instance == null)
  274.             
  275. instance = new ActorTwo_GloballState ();
  276.  
  277.  
  278.         
  279. return instance;
  280.     
  281. }
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.