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

原创 2016年08月29日 18:10:52

原文链接:http://blog.csdn.net/u013108312/article/details/52355425
新建一个文件夹:UIMgr
新建2个C#脚本:BaseUI.cs UIMgr.cs
里面的UIMgr.cs继承了EventNode。EventNode在前面有讲,这里重新给出一下。
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) && 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 && 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 && cmd.listener != null)
            {
                cmd.listener.FiniSh(ui);
            }
        }

        public void Failure()
        {
            if (cmd.createCanCall && 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;
        }
    }
}

原文链接:http://blog.csdn.net/u013108312/article/details/52355425

版权声明:欢迎转载,转载请注明原博客链接:http://blog.csdn.net/u013108312 和本文章的链接。谢谢合作。作者:CircleGood

相关文章推荐

Unity 客户端框架(六):UI框架

http://blog.csdn.net/lovethrain/article/details/52134167 引自百度:编写UI框架意义 打开,关闭,层级,页面跳转等管理问题集...
  • anypkv
  • anypkv
  • 2016年10月27日 23:54
  • 1377

Unity中简单 UI 管理类 - UIManager

进入下一个界面 // Enter Next UI; // MonoBehaviour can replace your UIBase Class; public T Enter(...

Unity框架——UI管理

1.BaseUIusing UnityEngine; using System.Collections;public class BaseUI : MonoBehaviour { [HideI...
  • Mortale
  • Mortale
  • 2017年02月10日 14:06
  • 708

Unity3D -- 简单的UI管理结构

Unity3D – 简单的UI管理结构使用Unity3D做一些小游戏原型的时候,虽然我们想做UI,但是又没有美术的支持,我们使用一个简单的UI模板,所有不需要做UI的小游戏直接使用就行了,也不必要每次...

Unity 游戏框架搭建 (八) 减少加班利器-QLog

为毛要实现这个工具?   在我小时候,每当游戏到了测试阶段,交给QA测试,QA测试了一会儿拿着设备过来说游戏闪退了。。。。当我拿到设备后测了好久Bug也没有复现,排查了好久也没有头绪,就算接了Bug...

[UnityUI]使用UI框架

unity的UI框架

Unity3D自学笔记——架构应用(一)用户登录

UGUI架构的应用案例

项目记录26--unity-tolua框架 View03-UIManager.lua

做为程序猿要懂得如果保持健康,对电脑时间太长很容易眼花,得脖子病,腰都疼,这星期六日组团到康宁去了,哈哈。一个字“疼”!!!! 废话不多少,把UIManager.lua个搞出来了。其实很简单,没有做什...

Unity客户端框架笔记(状态模式和策略模式在游戏中的应用)

最近花了几天时间梳理了一下新游戏的客户端框架,虽然本身就有相对明确的方向,但是在一开始写的时候还是有些混乱,不过最终梳理完成后,个人感觉代码清爽很多。         这篇文章不是设计模式的教学,而...

基于NGUI的unity界面管理的讨论

写在前面 刚刚做的项目,由于界面管理做的不太好,所以在开发的过程中出现了很多奇怪或难缠的bug,搞得我们几个写UI逻辑的越写越觉得没意思,想方设法的到处打补丁,后来也就是在这样的情况下,一直在总结开...
  • k46023
  • k46023
  • 2016年09月18日 10:23
  • 1962
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unity3d游戏开发框架-UI管理类 UIManager
举报原因:
原因补充:

(最多只允许输入30个字)