首先感謝姜雪松先生,大家可以去他的博客查看注釋以及代碼等,http://jxwgame.blog.51cto.com/943299/1613585
言歸正傳:
1.在開發項目的過程中,總是會遇到這樣的問題,從一個界面跳轉到另外一個界面,每次操作都要對一些對象進行顯示與隱藏,操作很麻煩也不方便維護修改。
2.於是很多人在這樣的一個基礎上開發出了很多便於維護和管理的UI框架或者UI狀態機。
3.所以簡單說下UI狀態機,來管理項目中各個界面之間的切換等
1.UI界面的基類
using System.Collections; using System.Collections.Generic; using UnityEngine; public class StateBehaviour : MonoBehaviour, IState { public FiniteStateMachine BelongToFSM { get; protected set; } public string StateName { get; protected set; } protected Dictionary<string, string> transitionMap = new Dictionary<string, string>(); public virtual void Init(FiniteStateMachine belongToFSM) { StateName = GetType().Name; BelongToFSM = belongToFSM; BelongToFSM.Register(StateName, this); foreach (KeyValuePair<string, string> pair in transitionMap) { BelongToFSM.State(StateName).On(pair.Key).Enter(pair.Value); } } public virtual void OnEnter(string prevState) { #if UNITY_EDITOR Debug.LogWarning("[" + BelongToFSM.Name + "] On Enter State: " + StateName + ", previous state is: " + prevState + transitionMap.Count); #endif } public virtual void OnExit(string nextState) { #if UNITY_EDITOR Debug.LogWarning("[" + BelongToFSM.Name + "] On Exit State: " + StateName + ", next state is: " + nextState); #endif } public virtual void OnUpdate() { } }
2.狀態機管理器
using UnityEngine; using System.Collections.Generic; /// <summary> /// 狀態機管理器 /// </summary> public class StateMachineManager : CSingleton<StateMachineManager> { //protected StateMachineManager() { } protected Dictionary<string, FiniteStateMachine> m_FiniteStateMachineDic = new Dictionary<string, FiniteStateMachine>(); public FiniteStateMachine GetFSM(string name) { FiniteStateMachine fsm; if (!m_FiniteStateMachineDic.TryGetValue(name, out fsm)) { return null; } return fsm; } public FiniteStateMachine UiFSM { get; protected set; } public FiniteStateMachine ControlUiFSM { get; protected set; } public void Awake() { UiFSM = AddFSM("UI FSM"); // 設置第一個狀態 UiFSM.EntryPoint(typeof(LoginPanelUI).Name); } public void Start() { // 設置第一個狀態 UiFSM.EntryPoint(typeof(LoginPanelUI).Name); //ControlUiFSM.EntryPoint(typeof(ConMainPanel).Name); } public FiniteStateMachine AddFSM(string name) { if (m_FiniteStateMachineDic.ContainsKey(name)) { return m_FiniteStateMachineDic[name]; } FiniteStateMachine fsm = new FiniteStateMachine(); fsm.Name = name; m_FiniteStateMachineDic.Add(fsm.Name, fsm); return fsm; } public bool RemoveFSM(string name) { return m_FiniteStateMachineDic.Remove(name); } public void Update() { foreach (KeyValuePair<string, FiniteStateMachine> pair in m_FiniteStateMachineDic) { pair.Value.Update(); } } public void OnDestroy() { m_FiniteStateMachineDic.Clear(); UiFSM.ClearAllStates(); UiFSM = null; ControlUiFSM.ClearAllStates(); ControlUiFSM = null; } }
3.登錄界面的UI腳本
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoginPanelUI : StateBehaviour { public Button btn; protected void Awake() { transitionMap["Login"] = typeof(MainPanelUI).Name; // 注意:該方法必須在transitionMap初始化后調用! Init(StateMachineManager.Instance.UiFSM); btn.onClick.AddListener(Onchlic_load); } public override void OnEnter(string prevState) { base.OnEnter(prevState); gameObject.SetActive(true); Debug.Log("OnEnter"); } public override void OnExit(string nextState) { base.OnExit(nextState); gameObject.SetActive(false); Debug.Log("OnExit"); } public override void OnUpdate() { base.OnUpdate(); Debug.Log("OnUpdate"); } public void Onchlic_load() { BelongToFSM.Trigger("Login"); } }
4.主菜單界面的UI腳本
using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class MainPanelUI : StateBehaviour { public Button btn_back; protected void Awake() { transitionMap["GoBack"] = typeof(LoginPanelUI).Name; // 注意:該方法必須在transitionMap初始化后調用! Init(StateMachineManager.Instance.UiFSM); gameObject.SetActive(false); btn_back.onClick.AddListener(GoBack); } public override void OnEnter(string prevState) { base.OnEnter(prevState); gameObject.SetActive(true); } public override void OnExit(string nextState) { base.OnExit(nextState); gameObject.SetActive(false); } public void GoBack() { BelongToFSM.Trigger("GoBack"); } }
5.公共類腳本
using System.Collections.Generic; using UnityEngine; using UnityEngine.VR; public class CommonManager : Singleton<CommonManager> { protected CommonManager() { } protected StateMachineManager m_StateMachineManager; protected void Awake() { m_StateMachineManager = StateMachineManager.Instance; m_StateMachineManager.Awake(); } protected void Start() { m_StateMachineManager.Start(); } protected void Update() { m_StateMachineManager.Update(); } }
6.好了,就這么多吧