美文网首页
Eevee框架14——EeveeUIFramwork与Addre

Eevee框架14——EeveeUIFramwork与Addre

作者: ShawnWeasley | 来源:发表于2020-09-03 14:34 被阅读0次

本来想用bind直接绑定Addressables的加载代码,无奈异步加载想不出来怎么改写API。

只好重写了EeveeUIFramwork中Page的加载逻辑,适配为Addressables的加载,同时个人感觉同步加载没啥用,直接移除了所有同步加载的API:

namespace EeveeFramework
{
    using System;
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using Object = UnityEngine.Object;
    using UnityEngine.AddressableAssets;

    #region define
    /// <summary>
    /// UI层级,根据不同层级设置父物体,如果展示层不够可自行扩展,需要创建对应的物体并调节相对位置
    /// </summary>
    public enum UIHierarchy
    {
        /// <summary>
        /// 背景图
        /// </summary>
        BackGround,
        /// <summary>
        /// 主界面
        /// </summary>
        MainMenu,
        /// <summary>
        /// 二级界面
        /// </summary>
        SecondaryMenu,
        /// <summary>
        /// 三级界面
        /// </summary>
        ThirdMenu,
        /// <summary>
        /// 普通弹出框
        /// </summary>
        Popup,
        /// <summary>
        /// 提示类弹出框
        /// </summary>
        AlwaysFront
    }

    /// <summary>
    /// UICollider碰撞遮挡设置
    /// </summary>
    public enum UICollider
    {
        /// <summary>
        /// 显示该界面不包含碰撞背景
        /// </summary>
        None,
        /// <summary>
        /// 碰撞透明背景
        /// </summary>
        Normal,
        /// <summary>
        /// 碰撞非透明背景
        /// </summary>
        WithBg,
    }
    #endregion

    /// <summary>
    /// 每个UI界面为一个Page,需设计层级关系但不区分管理,可自行从命名上区分,这里建议按照功能命名区分
    /// </summary>
    public abstract class UIPage
    {
        #region 变量
        //默认名为空字符串
        public string m_Name = string.Empty;

        //Page对应的UIRoot
        public UIRoot m_UIRoot = default(UIRoot);

        //page的id
        public int m_id = -1;

        //生成UI的类型,根据类型设定父物体
        public UIHierarchy m_UIHierarchy = UIHierarchy.MainMenu;

        //背景触发类型
        public UICollider m_Collider = UICollider.None;

        //加载UI的路径
        public string m_UIPath = string.Empty;

        //UI的物体
        public GameObject m_GameObject;
        public Transform m_Transform;

        //所有Pages的Dictionary
        private static Dictionary<string, UIPage> m_AllPages = new Dictionary<string, UIPage>();
        public static Dictionary<string, UIPage> AllPages
        { get { return m_AllPages; } }

        //Page是否打开
        protected bool m_IsActived = false;

        //刷新Page的数据
        private object m_Data = null;
        protected object Data { get { return m_Data; } }

        //加载ui的委托
        public static Func<string, Object> m_DelegateSyncLoadUI = null;
        public static Action<string, Action<Object>> m_DelegateAsyncLoadUI = null;

        //加载完成回调
        protected Action m_CallBack;
        #endregion
        #region virtual api

        /// <summary>
        /// 实例化Page
        /// </summary>
        /// <param name="go"></param>
        public virtual void Awake(GameObject go) { }

        /// <summary>
        /// 刷新Page
        /// </summary>
        public virtual void Refresh() { }

        /// <summary>
        /// 打开该Page
        /// </summary>
        public virtual void Active()
        {
            m_IsActived = true;
            this.m_GameObject.SetActive(m_IsActived);
        }

        /// <summary>
        /// 隐藏Page,不会清除数据
        /// </summary>
        public virtual void Hide()
        {
            this.m_GameObject.SetActive(false);
            m_IsActived = false;
            //隐藏时将此页的数据设为空
            this.m_Data = null;
        }
        #endregion

        #region internal api
        /// <summary>
        /// 构造函数
        /// </summary>
        private UIPage() { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="uIRoot">设置对应的UIRoot</param>
        /// <param name="type">设置要放的显示层级</param>
        /// <param name="uICollider">设置碰撞</param>
        public UIPage(UIRoot uIRoot, UIHierarchy type, UICollider uICollider)
        {
            if (uIRoot == null)
            {
                Debug.LogError("UIRoot is null");
                return;
            }

            this.m_UIRoot = uIRoot;
            this.m_UIHierarchy = type;
            this.m_Collider = uICollider;
            this.m_Name = this.GetType().ToString();
        }



        /// <summary>
        /// 异步ShowPage
        /// </summary>
        /// <param name="action">回调</param>
        protected void Show(Action action)
        {
            if (action != null) m_CallBack = action;

            if (this.m_GameObject == null && string.IsNullOrEmpty(m_UIPath) == false)
            {
                Addressables.InstantiateAsync(m_UIPath).Completed += OnLoadDone;
            }
            else
            {
                AnchorUIGameObject(this.m_GameObject);

                Active();

                Refresh();

                if (m_CallBack != null) m_CallBack();
            }
        }

        /// <summary>
        /// 加载完成
        /// </summary>
        /// <param name="obj">返回的物体</param>
        private void OnLoadDone(UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle<GameObject> obj)
        {
            try
            {
                m_GameObject = obj.Result;

                AnchorUIGameObject(m_GameObject);
                Awake(m_GameObject);

                Active();

                Refresh();

                if (m_CallBack != null) m_CallBack();
            }
            catch (System.Exception e)
            {
                Debug.LogError("加载错误:" + e);
            }
        }

        /// <summary>
        /// 设置Page的父级
        /// </summary>
        /// <param name="ui"></param>
        protected void AnchorUIGameObject(GameObject ui)
        {
            if (m_UIRoot == null)
            {
                Debug.LogError("UIRoot is null");
                return;
            }
            if (ui == null) return;

            this.m_GameObject = ui;
            this.m_Transform = ui.transform;
            ui.transform.SetParent(null, false);
            switch (m_UIHierarchy)
            {
                case UIHierarchy.BackGround:
                    ui.transform.SetParent(m_UIRoot.BackGround, false);
                    break;
                case UIHierarchy.MainMenu:
                    ui.transform.SetParent(m_UIRoot.MainMenu, false);
                    break;
                case UIHierarchy.SecondaryMenu:
                    ui.transform.SetParent(m_UIRoot.SecondaryMenu, false);
                    break;
                case UIHierarchy.ThirdMenu:
                    ui.transform.SetParent(m_UIRoot.ThirdMenu, false);
                    break;
                case UIHierarchy.Popup:
                    ui.transform.SetParent(m_UIRoot.Popup, false);
                    break;
                case UIHierarchy.AlwaysFront:
                    ui.transform.SetParent(m_UIRoot.AlwaysFront, false);
                    break;
            }
        }

        /// <summary>
        /// ToString
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return ">Name:" + m_Name + ",ID:" + m_id + ",Type:" + m_UIHierarchy.ToString() + ",Collider:" + m_Collider.ToString();
        }

        public bool IsActive => CheckIsActive();
        /// <summary>
        /// 是否开启
        /// </summary>
        /// <returns></returns>
        private bool CheckIsActive()
        {
            bool ret = m_GameObject != null && m_GameObject.activeSelf;
            return ret || m_IsActived;
        }

        #endregion

        #region static api
        #region ShowPage的重载
        /// <summary>
        /// 显示Page
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pageData">Page数据</param>
        /// <param name="action">回调</param>
        private static void ShowPage<T>(object pageData, Action action) where T : UIPage, new()
        {
            Type t = typeof(T);
            string pageName = t.ToString();

            if (m_AllPages.ContainsKey(pageName))
            {
                ShowPage(pageName, m_AllPages[pageName], pageData, action);
            }
            else
            {
                T instance = new T();
                ShowPage(pageName, instance, pageData, action);
            }
        }

        /// <summary>
        /// 打开已实例化过的Page
        /// </summary>
        /// <param name="pageName">pageName</param>
        /// <param name="pageInstance">page对象</param>
        /// <param name="pageData">page数据</param>
        /// <param name="action">回调</param>
        private static void ShowPage(string pageName, UIPage pageInstance, object pageData, Action action)
        {
            if (string.IsNullOrEmpty(pageName) || pageInstance == null)
            {
                Debug.LogError("[UI] show page error with :" + pageName + " maybe null instance.");
                return;
            }

            UIPage page = null;
            if (m_AllPages.ContainsKey(pageName))
            {
                page = m_AllPages[pageName];
            }
            else
            {
                m_AllPages.Add(pageName, pageInstance);
                page = pageInstance;
            }

            page.m_Data = pageData;

            page.Show(action);
        }

        /// <summary>
        /// 异步Show Page
        /// </summary>
        /// <typeparam name="T">T</typeparam>
        /// <param name="action">回调</param>
        public static void ShowPage<T>(Action action) where T : UIPage, new()
        {
            var pageData = new object();
            ShowPage<T>(pageData, action);
        }

        /// <summary>
        /// 异步Show Page
        /// </summary>
        /// <typeparam name="T">T</typeparam>
        public static void ShowPage<T>() where T : UIPage, new()
        {
            var pageData = new object();
            Action action = new Action(() => { });
            ShowPage<T>(pageData, action);
        }

        /// <summary>
        /// 异步Show Page
        /// </summary>
        /// <param name="pageName">pageName</param>
        /// <param name="pageInstance">实例对象</param>
        /// <param name="action"></param>
        public static void ShowPage(string pageName, UIPage pageInstance, Action action)
        {
            ShowPage(pageName, pageInstance, null, action);
        }

        #endregion
        #region ClosePage的重载
        /// <summary>
        /// 关闭Page
        /// </summary>
        /// <param name="target">实例对象</param>
        public static void ClosePage(UIPage target)
        {
            if (target == null) return;
            target.Hide();
        }

        /// <summary>
        /// 关闭Page
        /// </summary>
        /// <typeparam name="T">T</typeparam>
        public static void ClosePage<T>() where T : UIPage
        {
            Type t = typeof(T);
            string pageName = t.ToString();

            if (m_AllPages.ContainsKey(pageName))
            {
                ClosePage(m_AllPages[pageName]);
            }
            else
            {
                Debug.LogError(pageName + "havnt show yet!");
            }
        }

        /// <summary>
        /// 关闭Page
        /// </summary>
        /// <param name="pageName">pageName</param>
        public static void ClosePage(string pageName)
        {
            if (m_AllPages.ContainsKey(pageName))
            {
                ClosePage(m_AllPages[pageName]);
            }
            else
            {
                Debug.LogError(pageName + " havnt show yet!");
            }
        }
        #endregion
        #endregion
    }
}

这样就可以直接用了,如果没有Addressables的需要自己导入一下,下面是使用demo:
链接: https://pan.baidu.com/s/1aBtrEUx0SBhtwXHoRnzwjg
提取码: wv9s

相关文章

  • Eevee框架14——EeveeUIFramwork与Addre

    本来想用bind直接绑定Addressables的加载代码,无奈异步加载想不出来怎么改写API。 只好重写了Eev...

  • Eevee框架10——UI框架

    想要一个完美的UI框架,貌似太理想了,这里参考了唐老师、siki等能百度到的很多UI框架,发现大家都只是做了界面的...

  • Eevee框架1——序

    一个多月来学了很多东西,想综合起来做一个自己的框架,那就从今天开始,构建一个自己用着趁手的框架吧。 其实凉鞋的QF...

  • Eevee框架2——单例

    这里我们跟唐老师一样,先创建一个单例的基类,这样后续很多类都可以简单地实现单例。如果不了解单例的,唐老师的免费前几...

  • Eevee框架8——场景切换

    和对象池一样,本人场景切换用到的非常少(基本单场景搞定,因为个人感觉Unity自己加载第一个场景的速度,要远快于动...

  • Eevee框架7——Mono工具

    目前为止,我们已经有了单例、基于Mono的单例、对象池、事件系统四个轮子(工具),还需要继续造一些常用的工具。 一...

  • Eevee框架11——Json处理

    本篇开始我们开始进行数据的处理,在数据处理、资源处理完成后,我们就进行框架整合。数据处理首先是我们常用的Json处...

  • Eevee框架5——命名规范

    做着做着发现命名规则有必要统一一下,至少我本人需要统一一下,不能再随意命名了。本篇会根据开发过程中发现的命名问题,...

  • Eevee框架4——对象池

    这里先简述一下对象池的目的以及什么情况下需要对象池: 将部分需要持续性复用的物体(或对象)以隐藏/修改位置等方式先...

  • Eevee框架6——事件系统

    此处借鉴唐老师的事件系统。本人进行了书写规范化及一些非空判断避免报错等小优化。 如果对委托还不太了解的建议先看一下...

网友评论

      本文标题:Eevee框架14——EeveeUIFramwork与Addre

      本文链接:https://www.haomeiwen.com/subject/spvnsktx.html