Unity框架之狀態機


1、vs 注解快捷鍵?

2、接口 方法、屬性、字段?

3、生命周期(awake 、enable、start、update、fixedupdate、lateupdate、ongui)?

4、[HideInInspector]

第一步:IState 初步定義

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public interface IState{
 5     //獲取狀態機狀態
 6     uint GetStateID();
 7 
 8     //void OnEnter();
 9     //void OnLeave();
10     //等待補全
11     void OnEnter();
12     void OnLeave();
13 
14     //Unity 生命周期
15     void OnUpdate();
16     void OnFixedUpdate();
17     void OnLateUpdate();
18 }

 第二步:StateMachine 定義初步

 1 using UnityEngine;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 
 5 public class StateMachine {
 6     //使用字典 存儲狀態
 7     private Dictionary<uint, IState> mDictionaryState;
 8     //當前狀態
 9     private IState mCurrentState;
10 
11     public StateMachine()
12     {
13         mDictionaryState = new Dictionary<uint, IState>();
14         mCurrentState = null;
15     }
16     //添加狀態
17     public bool RegisterState(IState state)
18     {
19         if (state == null)
20         {
21             return false;
22         }
23         if (mDictionaryState.ContainsKey(state.GetStateID()))
24         {
25             return false;
26         }
27         mDictionaryState.Add(state.GetStateID(), state);
28         return true;
29     }
30     //獲取狀態
31     public IState GetState(uint stateID)
32     {
33         IState state = null;
34         mDictionaryState.TryGetValue(stateID, out state);
35         return state;
36     }
37     //停止狀態
38     public void StopState(object param1, object param2)
39     {
40 
41     }
42 }

第三步:補全 IState 替換掉步驟一中的兩個函數

1     //等待補全
2     //預留兩個參數備用
3     void OnEnter(StateMachine machine,IState preState,object param1,object param2);
4     void OnLeave(IState nextState,object param1,object param2);

 第四步:繼續完善StateMachine

 

  1 using UnityEngine;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 
  5 public class StateMachine {
  6     //使用字典 存儲狀態
  7     private Dictionary<uint, IState> mDictionaryState;
  8     //當前狀態
  9     private IState mCurrentState;
 10 
 11     public uint CurrentStateID //獲取當前狀態機ID
 12     {
 13         get
 14         {
 15             return mCurrentState == null ? 0 : mCurrentState.GetStateID();
 16         }
 17     }
 18 
 19     public IState CurrentState //獲取當前狀態機
 20     {
 21         get
 22         {
 23             return mCurrentState;
 24         }
 25     }
 26 
 27     public StateMachine() // 構造函數初始化
 28     {
 29         mDictionaryState = new Dictionary<uint, IState>();
 30         mCurrentState = null;
 31     }
 32 
 33     public bool RegisterState(IState state) //添加狀態
 34     {
 35         if (state == null)
 36         {
 37             return false;
 38         }
 39         if (mDictionaryState.ContainsKey(state.GetStateID()))
 40         {
 41             return false;
 42         }
 43         mDictionaryState.Add(state.GetStateID(), state);
 44         return true;
 45     }
 46 
 47     public IState GetState(uint stateID)//獲取狀態
 48     {
 49         IState state = null;
 50         mDictionaryState.TryGetValue(stateID, out state);
 51         return state;
 52     }
 53 
 54     public void StopState(object param1, object param2)//停止狀態
 55     {
 56         if (mCurrentState == null)
 57         {
 58             return;
 59         }
 60         mCurrentState.OnLeave(null, param1, param2);
 61         mCurrentState = null;
 62     }
 63 
 64     public bool UnRegisterState(uint StateID)//取消狀態注冊
 65     {
 66         if (!mDictionaryState.ContainsKey(StateID))
 67         {
 68             return false;
 69         }
 70         if (mCurrentState != null && mCurrentState.GetStateID() == StateID)
 71         {
 72             return false;
 73         }
 74         mDictionaryState.Remove(StateID);
 75         return true;
 76     }
 77     
 78     //切換狀態
 79 
 80     //切換狀態的委托
 81     public delegate void BetweenSwitchState(IState from, IState to, object param1, object param2);
 82     //切換狀態的回調
 83     public BetweenSwitchState BetweenSwitchStateCallBack = null;
 84     public bool SwitchState(uint newStateID, object param1, object param2)
 85     {
 86         //當前狀態切當前狀態 false
 87         if (mCurrentState != null && mCurrentState.GetStateID() == newStateID)
 88         {
 89             return false;
 90         }
 91         //切換到沒有注冊過的狀態 false
 92         IState newState = null;
 93         mDictionaryState.TryGetValue(newStateID, out newState);
 94         if (newState == null)
 95         {
 96             return false;
 97         }
 98         // 退出當前狀態
 99         if (mCurrentState != null)
100         {
101             mCurrentState.OnLeave(newState, param1, param2);
102         }
103 
104         //狀態切換間做的事
105         IState oldState = mCurrentState;
106         mCurrentState = newState;
107         if (BetweenSwitchStateCallBack != null)
108         {
109             BetweenSwitchStateCallBack(oldState, mCurrentState, param1, param2);
110         }
111         //進入新狀態
112         newState.OnEnter(this, oldState, param1, param2);
113         return true;
114     }
115 
116     public bool IsState(uint stateID)  //當前是否在某個狀態
117     {
118         return mCurrentState == null ? false : mCurrentState.GetStateID() == stateID;
119     }
120     public void OnUpdate()
121     {
122         if (mCurrentState != null)
123         {
124             mCurrentState.OnUpdate();
125         }
126     }
127     public void OnFixedUpdate()
128     {
129         if (mCurrentState != null)
130         {
131             mCurrentState.OnFixedUpdate();
132         }
133     }
134     public void OnLateUpdate()
135     {
136         if (mCurrentState != null)
137         {
138             mCurrentState.OnLateUpdate();
139         }
140     }
141 }

第五步:使用狀態機 Player(初步)

 

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class Player : MonoBehaviour {
 5     [HideInInspector]
 6     public StateMachine PlayerStateMachine = new StateMachine();
 7     void Awake () {
 8     }
 9 
10     void Update () {
11         PlayerStateMachine.OnUpdate();
12     }
13     void FixedUpdate()
14     {
15         PlayerStateMachine.OnFixedUpdate();
16     }
17     void LateUpdate()
18     {
19         PlayerStateMachine.OnLateUpdate();
20     }
21 }

 第六步:定義兩個狀態 實現接口 IState,定義 枚舉StateType

 

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class LeftRightMove : IState {
 5     private Player player;
 6     public LeftRightMove(Player player)
 7     {
 8         this.player = player;
 9     }
10     
11     public uint GetStateID()
12     {
13         return (uint)Player.StateType.LeftRight;
14     }
15 
16     public void OnEnter(StateMachine machine, IState prevState, object param1, object param2)
17     {
18         if (prevState != null)
19         {
20             Debug.Log("LeftRightMove  OnEnter PrevState is :" + prevState.GetStateID());
21         }
22         else
23         {
24             Debug.Log("LeftRightMove  OnEnter");
25         }
26         
27     }
28 
29     public void OnLeave(IState nextState, object param1, object param2)
30     {
31         Debug.Log("LeftRightMove OnLeave NextState is : " + nextState.GetStateID());
32     }
33 
34     private bool isLeft = true;
35     public void OnUpdate()
36     {
37         if (isLeft)
38         {
39             player.transform.position += new Vector3(-0.1f, 0.0f, 0.0f);
40             if (player.transform.position.x < -2f)
41             {
42                 isLeft = false;
43             }
44         }
45         else
46         {
47             player.transform.position += new Vector3(0.1f, 0.0f, 0.0f);
48             if (player.transform.position.x > 2f)
49             {
50                 isLeft = true;
51             }
52         }
53     }
54 
55     public void OnFixedUpdate()
56     {
57     }
58 
59     public void OnLateUpdate()
60     {
61     }
62 }
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class Player : MonoBehaviour {
 5     [HideInInspector]
 6     public StateMachine PlayerStateMachine = new StateMachine();
 7     public enum StateType : uint
 8     {
 9         LeftRight = 0,
10         UpDown = 1
11     }
12     void Awake () {
13         PlayerStateMachine.RegisterState(new LeftRightMove(this));
14         PlayerStateMachine.RegisterState(new UpDownMove(this));
15     }
16     void OnGUI() {
17         if (GUI.Button(new Rect(0,0,200,50),"LeftRight"))
18         {
19             PlayerStateMachine.SwitchState((uint)StateType.LeftRight, null, null);
20         }
21         if (GUI.Button(new Rect(0,100,200,50),"UpDown"))
22         {
23             PlayerStateMachine.SwitchState((uint)StateType.UpDown, null, null);
24         }
25     }
26     void Update () {
27         PlayerStateMachine.OnUpdate();
28     }
29     void FixedUpdate()
30     {
31         PlayerStateMachine.OnFixedUpdate();
32     }
33     void LateUpdate()
34     {
35         PlayerStateMachine.OnLateUpdate();
36     }
37 }

Demo 見鏈接、使用Unity 4.6.9f1編譯打包

鏈接:http://pan.baidu.com/s/1c03CQCo 密碼:6pcp

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM