• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

游戏开发

Unity3d框架-UI管理类 UIManager

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2018/1016/87.html

Unity3d游戏开发框架-UI管理类 UIManager

 

前面常州手游开发与培训已经给大家介绍U3D开发UI框架的的使用,本篇继续介绍Unity3D游戏开发框架系列,掌握UI管理类UIManager的使用。

 

新建一个文件夹:UIMgr

新建2C#脚本:BaseUI.cs UIMgr.cs

里面的UIMgr.cs继承了EventNodeEventNode在前面有讲,这里重新给出一下。

IResLoadListener.cs接口,资源加载回调

using UnityEngine;

using System.Collections;

public class BaseUI : MonoBehaviour 

    /// <summary>

    /// 当前界面名称

    /// </summary>

    [HideInInspector]

    public string UIName;

    private Transform mTransform;

    public Transform CacheTransform

   

        get

       

            if (mTransform == null) mTransform = this.transform;

            return mTransform;

       

   

    private GameObject mGo;

    public GameObject CacheGameObject

   

        get

       

            if (mGo == null) mGo = this.gameObject;

            return mGo;

       

   

    /// <summary>

    /// 显示当前UI

    /// </summary>

    /// <param name="param">附加参数</param>

    public void Show(object param = null)

   

        CacheGameObject.SetActive(true);

   

    /// <summary>

    /// 隐藏当前界面

    /// </summary>

    public void Hide()

   

        CacheGameObject.SetActive(false);

   

    /// <summary>

    /// 绑定脚本并且激活游戏物体会调用的方法

    /// </summary>

    void Awake() 

   

        OnAwake();

   

    /// <summary>

    /// 初始化UI主要用于寻找组件等

    /// </summary>

    public void UIInit()

   

        OnInit();

   

    /// <summary>

    /// 显示当前界面

    /// </summary>

    /// <param name="param">附加参数</param>

    protected virtual void OnShow(object param)

    /// <summary>

    /// 隐藏当前界面

    /// </summary>

    protected virtual void OnHide()

    /// <summary>

    /// 初始化当前界面

    /// </summary>

    protected virtual void OnInit()

    protected virtual void OnAwake()

    /// <summary>

    /// 删除当前UI 

    /// </summary>

    protected virtual void OnDestroy()

 

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

public class EventNode : MonoBehaviour

    /// <summary>

    /// 节点优先级

    /// </summary>

    public int EventNodePriority set; get;

    /// <summary>

    /// 所有消息集合

    /// </summary>

    private Dictionary<int, List<IEventListener>> mListeners = new Dictionary<int, List<IEventListener>>();

    /// <summary>

    /// 消息节点

    /// </summary>

    private List<EventNode> mNodeList = new List<EventNode>();

    /// <summary>

    /// 挂载一个消息节点到当前节点上

    /// </summary>

    /// <param name="node">消息节点</param>

    /// <returns>如果当前节点里面已经包含要添加的这个节点那么返回false</returns>

    public bool AttachEventNode(EventNode node)

   

        if (node == null)

       

            return false;

       

        if (mNodeList.Contains(node))

       

            return false;

       

        int pos = 0;

        for (int i = 0; i < mNodeList.Count;i++ )

       

            if (node.EventNodePriority > mNodeList[i].EventNodePriority)

           

                break;

           

            pos++;

       

        mNodeList.Insert(pos,node);

        return true;

   

    /// <summary>

    /// 卸载一个消息节点

    /// </summary>

    /// <param name="node">消息节点</param>

    /// <returns>如果节点不存在那么返回false</returns>

    public bool DetachEventNode(EventNode node)

   

        if (!mNodeList.Contains(node))

       

            return false;

       

        mNodeList.Remove(node);

        return true;

   

    /// <summary>

    /// 挂载一个消息监听器到当前的消息节点

    /// </summary>

    /// <param name="key">消息ID</param>

    /// <param name="listener">消息监听器</param>

    /// <returns>当前消息节点已经挂载了这个消息监听器那么返回false</returns>

    public bool AttachEventListener(int key,IEventListener listener)

   

        if (listener == null)

       

            return false;

       

        if (!mListeners.ContainsKey(key))

       

            mListeners.Add(key,new List<IEventListener>() listener );

            return true;

       

        if (mListeners[key].Contains(listener))

       

            return false;

       

        int pos = 0;

        for (int i = 0;i< mListeners[key].Count;i++ )

       

            if (listener.EventPriority() > mListeners[key][i].EventPriority())

           

                break;

           

            pos++;

       

        mListeners[key].Insert(pos,listener);

        return true;

   

    /// <summary>

    /// 卸载一个消息节点

    /// </summary>

    /// <returns>如果当前消息节点不存在那么返回false</returns>

    public bool DetachEventListener(int key,IEventListener listener)

   

       if (mListeners.ContainsKey(key) &amp;&amp; mListeners[key].Contains(listener))

      

           mListeners[key].Remove(listener);

           return true;

      

       return false;

   

    public void SendEvent(int key,object param1 = null,object param2 = null)

   

        DispatchEvent(key, param1, param2);

   

    /// <summary>

    /// 派发消息到子消息节点以及自己节点下的监听器上

    /// </summary>

    /// <param name="key">消息ID</param>

    /// <param name="param1"></param>

    /// <param name="param2"></param>

    /// <returns>如果中断消息返回true</returns>

    private bool DispatchEvent(int key,object param1,object param2)

   

        for (int i = 0; i < mNodeList.Count;i++ )

       

            if (mNodeList[i].DispatchEvent(key, param1, param2)) return true;

       

        return TriggerEvent(key, param1, param2);

   

    /// <summary>

    /// 消息触发

    /// </summary>

    /// <param name="key">消息id</param>

    /// <param name="param1"></param>

    /// <param name="param2"></param>

    /// <returns>是否中断</returns>

    private bool TriggerEvent(int key,object param1,object param2)

   

        if (!this.gameObject.activeSelf || !this.gameObject.activeInHierarchy || !this.enabled)

       

            return false;

       

        if (!mListeners.ContainsKey(key))

       

            return false;

       

        List<IEventListener> listeners = mListeners[key];

        for (int i = 0; i < listeners.Count; i++)

       

            if (listeners[i].HandleEvent(key, param1, param2)) return true;

       

        return false;

   

   void OnApplicationQuit()

   

        mListeners.Clear();

        mNodeList.Clear();

   

 

新建接口IResLoadListener.cs

using UnityEngine;

using System.Collections;

/// <summary>

/// 资源加载回调

/// </summary>

public interface IResLoadListener  

    void Finish(object asset);

    void Failure();

 

新建一个类UIMgr.cs继承EventNode

using UnityEngine;

using System.Collections;

using System;

using System.Collections.Generic;

public class UIMgr : EventNode 

    private static UIMgr mInstance;

    public static UIMgr Instance

   

        get

       

            return mInstance;

       

   

    /// <summary>

    /// 所有UI

    /// </summary>

    private Dictionary<string, BaseUI> mDicUI = new Dictionary<string, BaseUI>();

    /// <summary>

    /// 添加一个UI

    /// </summary>

    /// <param name="ui"></param>

    public void AddUI(BaseUI ui)

   

        if (ui != null)

       

            mDicUI[ui.UIName] = ui;

       

   

    /// <summary>

    /// 移除一个UI

    /// </summary>

    /// <param name="ui"></param>

    public void RemoveUI(BaseUI ui)

   

        if (ui != null &amp;&amp; mDicUI.ContainsKey(ui.UIName))

       

            mDicUI.Remove(ui.UIName);

       

   

    /// <summary>

    /// 所有命令集合

    /// </summary>

    public List<Command> cmdList = new List<Command>();

    internal Transform UIROOT = null;

    void Awake() 

   

        UIROOT = this.transform.FindChild("UIRoot");

        mInstance = this;

        DontDestroyOnLoad(this.gameObject);

   

    #region 创建UI

    /// <summary>

    /// 创建UI

    /// </summary>

    /// <param name="uiName">UI名称</param>

    /// <param name="type">要绑定的脚本</param>

    /// <param name="listener">创建完成的回调</param>

    public void CreateUI(string uiName, Type type, ILoadUIListener listener)

   

        cmdList.Add(Command.CreateCmd(type,uiName,listener));

   

    /// <summary>

    /// 创建UI的实体部分

    /// </summary>

    /// <param name="cmd">命令</param>

    private void _Create(Command cmd)

   

        BaseUI ui= null;

        mDicUI.TryGetValue(cmd.uiName, out ui);

        if (ui != null)

       

            if (cmd.listener != null) cmd.listener.FiniSh(ui);

       

        else

       

            ResMgr.Instance.Load(cmd.uiName,new LoadResFinish(cmd));

       

   

    #endregion

    #region 显示UI

    /// <summary>

    /// 显示一个UI界面  如果不存在就创建

    /// </summary>

    /// <param name="uiName">ui名称</param>

    /// <param name="type">要绑定的脚本</param>

    /// <param name="listener">如果界面不存在则会有界面加载完成后的回调</param>

    /// <param name="param">要传入的参数</param>

    public void ShowUI(string uiName, Type type, ILoadUIListener listener,object param = null,bool createCanCall = false)

   

        BaseUI ui = null;

        mDicUI.TryGetValue(uiName,out ui);

        if (ui == null)

       

            cmdList.Add(Command.CreateAndShowCmd(uiName,type,listener, param, createCanCall));

       

        else

       

            cmdList.Add(Command.ShowCmd(uiName, listener, param, createCanCall));

       

   

    /// <summary>

    /// 显示一个界面

    /// </summary>

    /// <param name="cmd"></param>

    private void _ShowUI(Command cmd)

   

        BaseUI ui = null;

        mDicUI.TryGetValue(cmd.uiName, out ui);

        if (ui != null)

       

            if (cmd.listener != null)

           

                cmd.listener.FiniSh(ui);

           

            ui.Show();

       

   

    #endregion

    #region  隐藏UI

    /// <summary>

    /// 隐藏这个UI

    /// </summary>

    /// <param name="uiName"></param>

    public void HideUI(string uiName)

   

        cmdList.Add(Command.HideCmd(uiName));

   

    private void _HideUI(Command cmd)

   

        Debug.Log("_HideUI " + cmd.uiName);

        BaseUI ui = null;

        mDicUI.TryGetValue(cmd.uiName, out ui);

        if (ui != null)

       

            ui.Hide();

       

   

#endregion

    #region  删除UI

    /// <summary>

    /// 删除UI

    /// </summary>

    /// <param name="uiName">UI名称</param>

    public void DestroyUI(string uiName)

   

        cmdList.Add(Command.DestroyCmd(uiName));

   

    private void _DestroyUI(Command cmd)

   

        BaseUI ui = null;

        mDicUI.TryGetValue(cmd.uiName, out ui);

        if (ui != null)

       

            mDicUI.Remove(ui.UIName);

            Destroy(ui.CacheGameObject);

       

   

    #endregion

    // Update is called every frame, if the MonoBehaviour is enabled.

    void Update() 

   

        if (cmdList.Count > 0)

       

            Command tempCmd = null;

            tempCmd = cmdList[0];

            if (tempCmd == null)

           

                cmdList.RemoveAt(0);

           

            else

           

                switch(tempCmd.cmdType)

               

                    case Command.CmdType.CreateAndShow:

                        _Create(tempCmd);

                        break;

                    case Command.CmdType.Create:

                        _Create(tempCmd);

                        break;

                    case Command.CmdType.Destroy:

                        _DestroyUI(tempCmd);

                        break;

                    case Command.CmdType.Hide:

                        _HideUI(tempCmd);

                        break;

                    case Command.CmdType.Show:

                        _ShowUI(tempCmd);

                        break;

               

                cmdList.RemoveAt(0);

           

       

   

    /// <summary>

    /// UI资源加载完成的回调

    /// </summary>

    public class LoadResFinish : IResLoadListener

   

        /// <summary>

        /// 命令

        /// </summary>

        public Command cmd;

        public LoadResFinish(Command _cmd)

       

            cmd = _cmd;

       

        public void Finish(object asset)

       

            if (cmd == null)

           

                return;

           

            GameObject go = Instantiate<GameObject>(asset as GameObject);

            go.SetActive(false);

            BaseUI ui =  go.AddComponent(cmd.type) as BaseUI;

            ui.UIInit();

            ui.UIName = cmd.uiName;

            go.gameObject.name = ui.UIName;

            ui.CacheTransform.SetParent(UIMgr.Instance.UIROOT, false);

            UIMgr.Instance.AddUI(ui);

            if (cmd.cmdType == Command.CmdType.CreateAndShow)

           

                UIMgr.Instance.ShowUI(cmd.uiName, cmd.type, cmd.listener);

           

            else if (cmd.createCanCall &amp;&amp; cmd.listener != null)

           

                cmd.listener.FiniSh(ui);

           

       

        public void Failure()

       

            if (cmd.createCanCall &amp;&amp; cmd.listener != null)

           

                cmd.listener.Failure();

           

       

   

    /// <summary>

    /// 界面加载回调

    /// </summary>

    public interface ILoadUIListener

   

        void FiniSh(BaseUI ui);

        void Failure();

   

    /// <summary>

    /// 操作UI命令集

    /// </summary>

    public class Command

   

        /// <summary>

        /// 命令类型

        /// </summary>

        public enum CmdType

       

            /// <summary>

            /// 创建

            /// </summary>

            CreateAndShow,

            /// <summary>

            /// 创建

            /// </summary>

            Create,

            /// <summary>

            /// 显示或者刷新

            /// </summary>

            Show,

            /// <summary>

            /// 隐藏

            /// </summary>

            Hide,

            /// <summary>

            /// 删除

            /// </summary>

            Destroy,

       

        /// <summary>

        /// UI名称

        /// </summary>

        public string uiName;

        /// <summary>

        /// 要绑定的脚本

        /// </summary>

        public Type type;

        /// <summary>

        /// 加载完成之后的回调

        /// </summary>

        public ILoadUIListener listener;

        /// <summary>

        /// 要传入的数据

        /// </summary>

        public object param;

        /// <summary>

        /// 命令类型

        /// </summary>

        public CmdType cmdType;

        /// <summary>

        /// 创建时候需要回调

        /// </summary>

        public bool createCanCall = true;

        /// <summary>

        /// 获取一个显示的命令

        /// </summary>

        /// <param name="_uiName">UI名称</param>

        /// <param name="_param">要传入的参数</param>

        public static Command CreateAndShowCmd(string uiName, Type type, ILoadUIListener listener, object param , bool createCanCall)

       

            Command cmd = new Command(CmdType.CreateAndShow, uiName, type);

            cmd.createCanCall = createCanCall;

            cmd.listener = listener;

            cmd.type = type;

            cmd.param = param;

            return cmd;

       

        /// <summary>

        /// 获取一个显示的命令

        /// </summary>

        /// <param name="_uiName">UI名称</param>

        /// <param name="_param">要传入的参数</param>

        public static Command ShowCmd(string _uiName,ILoadUIListener listener ,object _param, bool _createCanCall)

       

            Command cmd = new Command(CmdType.Show, _uiName, _param);

            cmd.createCanCall = _createCanCall;

            cmd.listener = listener;

            return cmd;

       

        /// <summary>

        /// 获取一个创建的命令

        /// </summary>

        /// <param name="_type">要绑定的脚本</param>

        /// <param name="_listener">加载完成之后的回调</param>

        public static Command CreateCmd(Type _type,string _uiName, ILoadUIListener _listener)

       

            return new Command(CmdType.Create, _uiName, _type, _listener);

       

        /// <summary>

        /// 获取一个隐藏命令

        /// </summary>

        /// <param name="_uiName">要隐藏的UI名称</param>

        /// <returns></returns>

        public static Command HideCmd(string _uiName)

       

            return new Command(CmdType.Hide, _uiName,null);

       

        /// <summary>

        /// 获取一个删除的命令

        /// </summary>

        /// <param name="_uiName">UI名称</param>

        /// <returns></returns>

        public static Command DestroyCmd(string _uiName)

       

            return new Command(CmdType.Destroy, _uiName, null);

       

        /// <summary>

        /// 构造函数

        /// </summary>

        /// <param name="_cmdType">命令类型</param>

        /// <param name="_uiName">UI名称</param>

        /// <param name="_param">要传入的参数</param>

        public Command(CmdType _cmdType, string _uiName, object _param)

       

            uiName = _uiName;

            cmdType = _cmdType;

            param = _param;

       

        /// <summary>

        /// 构造

        /// </summary>

        /// <param name="_cmdType">命令类型</param>

        /// <param name="_type">要绑定的脚本</param>

        /// <param name="_listener">加载完成之后的回调</param>

        public Command(CmdType _cmdType,string _uiName,Type _type,ILoadUIListener _listener)

       

            cmdType = _cmdType;

            type = _type;

            listener = _listener;

            uiName = _uiName;

       

   

 



上篇:上一篇:UGUI文本下划线实现
下篇:下一篇:Unity3D GameView-BaseWindow