Eevee框架14——EeveeUIFramwork与Addre
2020-09-03 本文已影响0人
ShawnWeasley
本来想用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