unity中的UI狀態機,用於各界面之間的切換和跳轉


首先感謝姜雪松先生,大家可以去他的博客查看注釋以及代碼等,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.好了,就這么多吧


免責聲明!

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



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