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
