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.好了,就这么多吧

posted @ 2018-06-01 16:03  nanyang0310  阅读(9874)  评论(0编辑  收藏  举报