mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
UIWindow
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using UnityEngine;
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace TEngine
|
namespace TEngine
|
||||||
{
|
{
|
||||||
@@ -25,5 +26,10 @@ namespace TEngine
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -60,7 +60,7 @@ namespace TEngine
|
|||||||
rectTransform.anchorMax = m_Half;
|
rectTransform.anchorMax = m_Half;
|
||||||
rectTransform.anchoredPosition = Vector2.zero;
|
rectTransform.anchoredPosition = Vector2.zero;
|
||||||
// return obj.GetOrAddComponent<UIWindow>();
|
// return obj.GetOrAddComponent<UIWindow>();
|
||||||
return new UIWindow();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -3,11 +3,11 @@
|
|||||||
public interface IUIBehaviour
|
public interface IUIBehaviour
|
||||||
{
|
{
|
||||||
void ScriptGenerator();
|
void ScriptGenerator();
|
||||||
|
void BindMemberProperty();
|
||||||
void RegisterEvent();
|
void RegisterEvent();
|
||||||
void OnCreate();
|
void OnCreate();
|
||||||
void OnUpdate(float elapseSeconds, float realElapseSeconds);
|
void OnRefresh();
|
||||||
void OnClose(bool isShutdown, object userData);
|
void OnUpdate();
|
||||||
void OnPause();
|
void OnDestroy();
|
||||||
void OnResume();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,73 @@
|
|||||||
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 打开窗口操作句柄。
|
||||||
|
/// </summary>
|
||||||
|
public class OpenWindowOperation : GameAsyncOperation
|
||||||
|
{
|
||||||
|
private enum ESteps
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Waiting,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly AssetOperationHandle _handle;
|
||||||
|
private ESteps _steps = ESteps.None;
|
||||||
|
|
||||||
|
internal OpenWindowOperation(AssetOperationHandle handle)
|
||||||
|
{
|
||||||
|
_handle = handle;
|
||||||
|
}
|
||||||
|
protected override void OnStart()
|
||||||
|
{
|
||||||
|
_steps = ESteps.Waiting;
|
||||||
|
}
|
||||||
|
protected override void OnUpdate()
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_steps == ESteps.Waiting)
|
||||||
|
{
|
||||||
|
if (_handle.IsValid == false)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = $"{nameof(AssetOperationHandle)} is invalid.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_handle.IsDone == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_handle.AssetObject == null)
|
||||||
|
{
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Status = EOperationStatus.Failed;
|
||||||
|
Error = $"{nameof(AssetOperationHandle.AssetObject)} is null.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_steps = ESteps.Done;
|
||||||
|
Status = EOperationStatus.Succeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 等待异步实例化结束
|
||||||
|
/// </summary>
|
||||||
|
public void WaitForAsyncComplete()
|
||||||
|
{
|
||||||
|
if (_handle != null)
|
||||||
|
{
|
||||||
|
if (_steps == ESteps.Done)
|
||||||
|
return;
|
||||||
|
_handle.WaitForAsyncComplete();
|
||||||
|
OnUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8ebdde8ab5014a73983249d935b415e4
|
||||||
|
timeCreated: 1680520779
|
@@ -1,7 +1,34 @@
|
|||||||
namespace TEngine
|
using YooAsset;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
{
|
{
|
||||||
|
public enum UIBaseType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Window,
|
||||||
|
Widget,
|
||||||
|
}
|
||||||
|
|
||||||
public class UIBase
|
public class UIBase
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 所属的window。
|
||||||
|
/// </summary>
|
||||||
|
protected UIBase parent = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// UI父节点。
|
||||||
|
/// </summary>
|
||||||
|
public UIBase Parent => parent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// UI类型。
|
||||||
|
/// </summary>
|
||||||
|
public virtual UIBaseType BaseType => UIBaseType.None;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源操作句柄。
|
||||||
|
/// </summary>
|
||||||
|
public AssetOperationHandle Handle { protected set; get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,3 +1,3 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 62c603695cbe4b8bb59a94d907ca7f65
|
guid: aa3dc52076b14039bc355c825c7f29de
|
||||||
timeCreated: 1680514241
|
timeCreated: 1680526167
|
@@ -1,9 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
using UnityEngine.UI;
|
||||||
|
using YooAsset;
|
||||||
|
|
||||||
namespace TEngine
|
namespace TEngine
|
||||||
{
|
{
|
||||||
|
public enum EUIGroup
|
||||||
|
{
|
||||||
|
Bottom,
|
||||||
|
UI,
|
||||||
|
Top,
|
||||||
|
Tips,
|
||||||
|
System,
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// UI组件。
|
/// UI组件。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -12,35 +23,34 @@ namespace TEngine
|
|||||||
{
|
{
|
||||||
private const int DefaultPriority = 0;
|
private const int DefaultPriority = 0;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private Transform m_InstanceRoot = null;
|
||||||
private Transform m_InstanceRoot = null;
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private Camera m_UICamera = null;
|
||||||
private Camera m_UICamera = null;
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private string m_UIWindowHelperTypeName = "TEngine.DefaultUIWindowHelper";
|
||||||
private string m_UIWindowHelperTypeName = "TEngine.DefaultUIWindowHelper";
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private UIWindowHelperBase mCustomUIWindowHelper = null;
|
||||||
private UIWindowHelperBase mCustomUIWindowHelper = null;
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private string m_UIGroupHelperTypeName = "TEngine.DefaultUIGroupHelper";
|
||||||
private string m_UIGroupHelperTypeName = "TEngine.DefaultUIGroupHelper";
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private UIGroupHelperBase m_CustomUIGroupHelper = null;
|
||||||
private UIGroupHelperBase m_CustomUIGroupHelper = null;
|
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] private UIGroup[] m_UIGroups = null;
|
||||||
private UIGroup[] m_UIGroups = null;
|
|
||||||
|
private readonly List<UIWindow> _stack = new List<UIWindow>(100);
|
||||||
|
|
||||||
public const int GROUP_DEEP = 10000;
|
public const int GROUP_DEEP = 10000;
|
||||||
public const int WINDOWS_DEEP = 100;
|
public const int WINDOW_DEEP = 100;
|
||||||
|
public const int WINDOW_HIDE_LAYER = 2; // Ignore Raycast
|
||||||
|
public const int WINDOW_SHOW_LAYER = 5; // UI
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// UI根节点。
|
/// UI根节点。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Transform UIRoot => m_InstanceRoot;
|
public Transform UIRoot => m_InstanceRoot;
|
||||||
|
|
||||||
|
public static Transform UIRootStatic;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// UI根节点。
|
/// UI根节点。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -51,11 +61,6 @@ namespace TEngine
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int UIGroupCount => m_UIGroups?.Length ?? 0;
|
public int UIGroupCount => m_UIGroups?.Length ?? 0;
|
||||||
|
|
||||||
protected override void Awake()
|
|
||||||
{
|
|
||||||
base.Awake();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
RootComponent rootComponent = GameEntry.GetComponent<RootComponent>();
|
RootComponent rootComponent = GameEntry.GetComponent<RootComponent>();
|
||||||
@@ -85,6 +90,7 @@ namespace TEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_InstanceRoot.gameObject.layer = LayerMask.NameToLayer("UI");
|
m_InstanceRoot.gameObject.layer = LayerMask.NameToLayer("UI");
|
||||||
|
UIRootStatic = m_InstanceRoot;
|
||||||
|
|
||||||
for (int i = 0; i < m_UIGroups.Length; i++)
|
for (int i = 0; i < m_UIGroups.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -96,6 +102,26 @@ namespace TEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
CloseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
int count = _stack.Count;
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
if (_stack.Count != count)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var window = _stack[i];
|
||||||
|
window.InternalUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 增加界面组。
|
/// 增加界面组。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -120,5 +146,366 @@ namespace TEngine
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region 设置安全区域
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置屏幕安全区域(异形屏支持)。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="safeRect">安全区域</param>
|
||||||
|
public static void ApplyScreenSafeRect(Rect safeRect)
|
||||||
|
{
|
||||||
|
CanvasScaler scaler = UIRootStatic.GetComponentInParent<CanvasScaler>();
|
||||||
|
if (scaler == null)
|
||||||
|
{
|
||||||
|
Log.Error($"Not found {nameof(CanvasScaler)} !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert safe area rectangle from absolute pixels to UGUI coordinates
|
||||||
|
float rateX = scaler.referenceResolution.x / Screen.width;
|
||||||
|
float rateY = scaler.referenceResolution.y / Screen.height;
|
||||||
|
float posX = (int)(safeRect.position.x * rateX);
|
||||||
|
float posY = (int)(safeRect.position.y * rateY);
|
||||||
|
float width = (int)(safeRect.size.x * rateX);
|
||||||
|
float height = (int)(safeRect.size.y * rateY);
|
||||||
|
|
||||||
|
float offsetMaxX = scaler.referenceResolution.x - width - posX;
|
||||||
|
float offsetMaxY = scaler.referenceResolution.y - height - posY;
|
||||||
|
|
||||||
|
// 注意:安全区坐标系的原点为左下角
|
||||||
|
var rectTrans = UIRootStatic.transform as RectTransform;
|
||||||
|
if (rectTrans != null)
|
||||||
|
{
|
||||||
|
rectTrans.offsetMin = new Vector2(posX, posY); //锚框状态下的屏幕左下角偏移向量
|
||||||
|
rectTrans.offsetMax = new Vector2(-offsetMaxX, -offsetMaxY); //锚框状态下的屏幕右上角偏移向量
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模拟IPhoneX异形屏
|
||||||
|
/// </summary>
|
||||||
|
public static void SimulateIPhoneXNotchScreen()
|
||||||
|
{
|
||||||
|
Rect rect;
|
||||||
|
if (Screen.height > Screen.width)
|
||||||
|
{
|
||||||
|
// 竖屏Portrait
|
||||||
|
float deviceWidth = 1125;
|
||||||
|
float deviceHeight = 2436;
|
||||||
|
rect = new Rect(0f / deviceWidth, 102f / deviceHeight, 1125f / deviceWidth, 2202f / deviceHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 横屏Landscape
|
||||||
|
float deviceWidth = 2436;
|
||||||
|
float deviceHeight = 1125;
|
||||||
|
rect = new Rect(132f / deviceWidth, 63f / deviceHeight, 2172f / deviceWidth, 1062f / deviceHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect safeArea = new Rect(Screen.width * rect.x, Screen.height * rect.y, Screen.width * rect.width, Screen.height * rect.height);
|
||||||
|
ApplyScreenSafeRect(safeArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有层级下顶部的窗口名称。
|
||||||
|
/// </summary>
|
||||||
|
public string GetTopWindow()
|
||||||
|
{
|
||||||
|
if (_stack.Count == 0)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIWindow topWindow = _stack[_stack.Count - 1];
|
||||||
|
return topWindow.WindowName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定层级下顶部的窗口名称。
|
||||||
|
/// </summary>
|
||||||
|
public string GetTopWindow(int layer)
|
||||||
|
{
|
||||||
|
UIWindow lastOne = null;
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
if (_stack[i].WindowLayer == layer)
|
||||||
|
lastOne = _stack[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastOne == null)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
return lastOne.WindowName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否有任意窗口正在加载。
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAnyLoading()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
var window = _stack[i];
|
||||||
|
if (window.IsLoadDone == false)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询窗口是否存在。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">界面类型。</typeparam>
|
||||||
|
/// <returns>是否存在。</returns>
|
||||||
|
public bool HasWindow<T>()
|
||||||
|
{
|
||||||
|
return HasWindow(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询窗口是否存在。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">界面类型。</param>
|
||||||
|
/// <returns>是否存在。</returns>
|
||||||
|
public bool HasWindow(Type type)
|
||||||
|
{
|
||||||
|
return IsContains(type.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步打开窗口。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userDatas">用户自定义数据。</param>
|
||||||
|
/// <returns>打开窗口操作句柄。</returns>
|
||||||
|
public OpenWindowOperation ShowUIAsync<T>(params System.Object[] userDatas) where T : UIWindow
|
||||||
|
{
|
||||||
|
return ShowUIAsync(typeof(T), userDatas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步打开窗口。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">界面类型。</param>
|
||||||
|
/// <param name="userDatas">用户自定义数据。</param>
|
||||||
|
/// <returns>打开窗口操作句柄。</returns>
|
||||||
|
public OpenWindowOperation ShowUIAsync(Type type, params System.Object[] userDatas)
|
||||||
|
{
|
||||||
|
string windowName = type.FullName;
|
||||||
|
|
||||||
|
// 如果窗口已经存在
|
||||||
|
if (IsContains(windowName))
|
||||||
|
{
|
||||||
|
UIWindow window = GetWindow(windowName);
|
||||||
|
Pop(window); //弹出窗口
|
||||||
|
Push(window); //重新压入
|
||||||
|
window.TryInvoke(OnWindowPrepare, userDatas);
|
||||||
|
var operation = new OpenWindowOperation(window.Handle);
|
||||||
|
YooAssets.StartOperation(operation);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UIWindow window = CreateInstance(type);
|
||||||
|
Push(window); //首次压入
|
||||||
|
window.InternalLoad(window.AssetName, OnWindowPrepare, userDatas);
|
||||||
|
var operation = new OpenWindowOperation(window.Handle);
|
||||||
|
YooAssets.StartOperation(operation);
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 同步打开窗口。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">窗口类。</typeparam>
|
||||||
|
/// <param name="userDatas">用户自定义数据。</param>
|
||||||
|
/// <returns>打开窗口操作句柄。</returns>
|
||||||
|
public OpenWindowOperation ShowUI<T>(params System.Object[] userDatas) where T : UIWindow
|
||||||
|
{
|
||||||
|
var operation = ShowUIAsync(typeof(T), userDatas);
|
||||||
|
operation.WaitForAsyncComplete();
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 同步打开窗口。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="userDatas"></param>
|
||||||
|
/// <returns>打开窗口操作句柄。</returns>
|
||||||
|
public OpenWindowOperation ShowUI(Type type, params System.Object[] userDatas)
|
||||||
|
{
|
||||||
|
var operation = ShowUIAsync(type, userDatas);
|
||||||
|
operation.WaitForAsyncComplete();
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭窗口
|
||||||
|
/// </summary>
|
||||||
|
public void CloseWindow<T>() where T : UIWindow
|
||||||
|
{
|
||||||
|
CloseWindow(typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseWindow(Type type)
|
||||||
|
{
|
||||||
|
string windowName = type.FullName;
|
||||||
|
UIWindow window = GetWindow(windowName);
|
||||||
|
if (window == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window.InternalDestroy();
|
||||||
|
Pop(window);
|
||||||
|
OnSortWindowDepth(window.WindowLayer);
|
||||||
|
OnSetWindowVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭所有窗口。
|
||||||
|
/// </summary>
|
||||||
|
public void CloseAll()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
UIWindow window = _stack[i];
|
||||||
|
window.InternalDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
_stack.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnWindowPrepare(UIWindow window)
|
||||||
|
{
|
||||||
|
OnSortWindowDepth(window.WindowLayer);
|
||||||
|
window.InternalCreate();
|
||||||
|
window.InternalRefresh();
|
||||||
|
OnSetWindowVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSortWindowDepth(int layer)
|
||||||
|
{
|
||||||
|
int depth = layer;
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
if (_stack[i].WindowLayer == layer)
|
||||||
|
{
|
||||||
|
_stack[i].Depth = depth;
|
||||||
|
depth += WINDOW_DEEP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSetWindowVisible()
|
||||||
|
{
|
||||||
|
bool isHideNext = false;
|
||||||
|
for (int i = _stack.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
UIWindow window = _stack[i];
|
||||||
|
if (isHideNext == false)
|
||||||
|
{
|
||||||
|
window.Visible = true;
|
||||||
|
if (window.IsPrepare && window.FullScreen)
|
||||||
|
{
|
||||||
|
isHideNext = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UIWindow CreateInstance(Type type)
|
||||||
|
{
|
||||||
|
UIWindow window = Activator.CreateInstance(type) as UIWindow;
|
||||||
|
WindowAttribute attribute = Attribute.GetCustomAttribute(type, typeof(WindowAttribute)) as WindowAttribute;
|
||||||
|
|
||||||
|
if (window == null)
|
||||||
|
throw new Exception($"Window {type.FullName} create instance failed.");
|
||||||
|
if (attribute == null)
|
||||||
|
throw new Exception($"Window {type.FullName} not found {nameof(WindowAttribute)} attribute.");
|
||||||
|
|
||||||
|
string assetName = string.IsNullOrEmpty(attribute.AssetName) ? type.Name : attribute.AssetName;
|
||||||
|
window.Init(type.FullName, attribute.WindowLayer, attribute.FullScreen, assetName);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UIWindow GetWindow(string windowName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
UIWindow window = _stack[i];
|
||||||
|
if (window.WindowName == windowName)
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsContains(string windowName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
UIWindow window = _stack[i];
|
||||||
|
if (window.WindowName == windowName)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Push(UIWindow window)
|
||||||
|
{
|
||||||
|
// 如果已经存在
|
||||||
|
if (IsContains(window.WindowName))
|
||||||
|
throw new System.Exception($"Window {window.WindowName} is exist.");
|
||||||
|
|
||||||
|
// 获取插入到所属层级的位置
|
||||||
|
int insertIndex = -1;
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
if (window.WindowLayer == _stack[i].WindowLayer)
|
||||||
|
{
|
||||||
|
insertIndex = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有所属层级,找到相邻层级
|
||||||
|
if (insertIndex == -1)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _stack.Count; i++)
|
||||||
|
{
|
||||||
|
if (window.WindowLayer > _stack[i].WindowLayer)
|
||||||
|
{
|
||||||
|
insertIndex = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是空栈或没有找到插入位置
|
||||||
|
if (insertIndex == -1)
|
||||||
|
{
|
||||||
|
insertIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最后插入到堆栈
|
||||||
|
_stack.Insert(insertIndex, window);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Pop(UIWindow window)
|
||||||
|
{
|
||||||
|
// 从堆栈里移除
|
||||||
|
_stack.Remove(window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,7 +0,0 @@
|
|||||||
namespace TEngine
|
|
||||||
{
|
|
||||||
public class UIManager
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5bd4d4995a5241e3b2df04687b757f47
|
|
||||||
timeCreated: 1680511416
|
|
62
Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs
Normal file
62
Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public abstract class UIWidget:UIBase,IUIBehaviour
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 所属的窗口。
|
||||||
|
/// </summary>
|
||||||
|
public UIWindow OwnerWindow
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var parentUI = base.parent;
|
||||||
|
while (parentUI != null)
|
||||||
|
{
|
||||||
|
if (parentUI.BaseType == UIBaseType.Window)
|
||||||
|
{
|
||||||
|
return parentUI as UIWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
parentUI = parentUI.Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ScriptGenerator()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void BindMemberProperty()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void RegisterEvent()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnCreate()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnRefresh()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnUpdate()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnDestroy()
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs.meta
Normal file
3
Assets/TEngine/Runtime/GameFramework/UI/UIWidget.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 497ec3b265be4f81aead015ca3aa91d7
|
||||||
|
timeCreated: 1680526019
|
@@ -1,7 +1,474 @@
|
|||||||
namespace TEngine
|
using System;
|
||||||
{
|
using UnityEngine;
|
||||||
public class UIWindow
|
using UnityEngine.UI;
|
||||||
{
|
using YooAsset;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public abstract class UIWindow : UIBase, IUIBehaviour
|
||||||
|
{
|
||||||
|
private System.Action<UIWindow> _prepareCallback;
|
||||||
|
|
||||||
|
private System.Object[] _userDatas;
|
||||||
|
|
||||||
|
private bool _isCreate = false;
|
||||||
|
|
||||||
|
private GameObject _panel;
|
||||||
|
|
||||||
|
private Canvas _canvas;
|
||||||
|
|
||||||
|
private Canvas[] _childCanvas;
|
||||||
|
|
||||||
|
private GraphicRaycaster _raycaster;
|
||||||
|
|
||||||
|
private GraphicRaycaster[] _childRaycaster;
|
||||||
|
|
||||||
|
public override UIBaseType BaseType => UIBaseType.Window;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口矩阵位置组件。
|
||||||
|
/// </summary>
|
||||||
|
public RectTransform transform => _panel.transform as RectTransform;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口的实例资源对象。
|
||||||
|
/// </summary>
|
||||||
|
public GameObject gameObject => _panel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口名称。
|
||||||
|
/// </summary>
|
||||||
|
public string WindowName { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口层级。
|
||||||
|
/// </summary>
|
||||||
|
public int WindowLayer { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 资源定位地址。
|
||||||
|
/// </summary>
|
||||||
|
public string AssetName { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为全屏窗口
|
||||||
|
/// </summary>
|
||||||
|
public bool FullScreen { private set; get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义数据。
|
||||||
|
/// </summary>
|
||||||
|
public System.Object UserData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_userDatas != null && _userDatas.Length >= 1)
|
||||||
|
{
|
||||||
|
return _userDatas[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义数据集。
|
||||||
|
/// </summary>
|
||||||
|
public System.Object[] UserDatas => _userDatas;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口深度值
|
||||||
|
/// </summary>
|
||||||
|
public int Depth
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_canvas != null)
|
||||||
|
{
|
||||||
|
return _canvas.sortingOrder;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_canvas != null)
|
||||||
|
{
|
||||||
|
if (_canvas.sortingOrder == value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置父类
|
||||||
|
_canvas.sortingOrder = value;
|
||||||
|
|
||||||
|
// 设置子类
|
||||||
|
int depth = value;
|
||||||
|
for (int i = 0; i < _childCanvas.Length; i++)
|
||||||
|
{
|
||||||
|
var canvas = _childCanvas[i];
|
||||||
|
if (canvas != _canvas)
|
||||||
|
{
|
||||||
|
depth += 5; //注意递增值
|
||||||
|
canvas.sortingOrder = depth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 虚函数
|
||||||
|
if (_isCreate)
|
||||||
|
{
|
||||||
|
OnSortDepth(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口可见性
|
||||||
|
/// </summary>
|
||||||
|
public bool Visible
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_canvas != null)
|
||||||
|
{
|
||||||
|
return _canvas.gameObject.layer == UIComponent.WINDOW_SHOW_LAYER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_canvas != null)
|
||||||
|
{
|
||||||
|
int setLayer = value ? UIComponent.WINDOW_SHOW_LAYER : UIComponent.WINDOW_HIDE_LAYER;
|
||||||
|
if (_canvas.gameObject.layer == setLayer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 显示设置
|
||||||
|
_canvas.gameObject.layer = setLayer;
|
||||||
|
for (int i = 0; i < _childCanvas.Length; i++)
|
||||||
|
{
|
||||||
|
_childCanvas[i].gameObject.layer = setLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 交互设置
|
||||||
|
Interactable = value;
|
||||||
|
|
||||||
|
// 虚函数
|
||||||
|
if (_isCreate)
|
||||||
|
{
|
||||||
|
OnSetVisible(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口交互性
|
||||||
|
/// </summary>
|
||||||
|
private bool Interactable
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_raycaster != null)
|
||||||
|
{
|
||||||
|
return _raycaster.enabled;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_raycaster != null)
|
||||||
|
{
|
||||||
|
_raycaster.enabled = value;
|
||||||
|
for (int i = 0; i < _childRaycaster.Length; i++)
|
||||||
|
{
|
||||||
|
_childRaycaster[i].enabled = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否加载完毕
|
||||||
|
/// </summary>
|
||||||
|
internal bool IsLoadDone => Handle.IsDone;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否准备完毕
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPrepare { private set; get; }
|
||||||
|
|
||||||
|
|
||||||
|
public void Init(string name, int layer, bool fullScreen, string assetName)
|
||||||
|
{
|
||||||
|
WindowName = name;
|
||||||
|
WindowLayer = layer;
|
||||||
|
FullScreen = fullScreen;
|
||||||
|
AssetName = assetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 代码自动生成绑定。
|
||||||
|
/// </summary>
|
||||||
|
public virtual void ScriptGenerator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 绑定UI成员元素。
|
||||||
|
/// </summary>
|
||||||
|
public virtual void BindMemberProperty()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册事件。
|
||||||
|
/// </summary>
|
||||||
|
public virtual void RegisterEvent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口创建。
|
||||||
|
/// </summary>
|
||||||
|
public virtual void OnCreate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口刷新
|
||||||
|
/// </summary>
|
||||||
|
public virtual void OnRefresh()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口更新
|
||||||
|
/// </summary>
|
||||||
|
public virtual void OnUpdate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 窗口销毁
|
||||||
|
/// </summary>
|
||||||
|
public virtual void OnDestroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Close()
|
||||||
|
{
|
||||||
|
GameModule.UI.CloseWindow(this.GetType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当触发窗口的层级排序
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnSortDepth(int depth)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当因为全屏遮挡触发窗口的显隐
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnSetVisible(bool visible)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void TryInvoke(System.Action<UIWindow> prepareCallback, System.Object[] userDatas)
|
||||||
|
{
|
||||||
|
_userDatas = userDatas;
|
||||||
|
if (IsPrepare)
|
||||||
|
{
|
||||||
|
prepareCallback?.Invoke(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_prepareCallback = prepareCallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InternalLoad(string location, System.Action<UIWindow> prepareCallback, System.Object[] userDatas)
|
||||||
|
{
|
||||||
|
if (Handle != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_prepareCallback = prepareCallback;
|
||||||
|
_userDatas = userDatas;
|
||||||
|
Handle = YooAssets.LoadAssetAsync<GameObject>(location);
|
||||||
|
Handle.Completed += Handle_Completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InternalCreate()
|
||||||
|
{
|
||||||
|
if (_isCreate == false)
|
||||||
|
{
|
||||||
|
_isCreate = true;
|
||||||
|
OnCreate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InternalRefresh()
|
||||||
|
{
|
||||||
|
OnRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InternalUpdate()
|
||||||
|
{
|
||||||
|
if (IsPrepare)
|
||||||
|
{
|
||||||
|
OnUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void InternalDestroy()
|
||||||
|
{
|
||||||
|
_isCreate = false;
|
||||||
|
|
||||||
|
RemoveAllUIEvent();
|
||||||
|
|
||||||
|
// 注销回调函数
|
||||||
|
_prepareCallback = null;
|
||||||
|
|
||||||
|
// 卸载面板资源
|
||||||
|
if (Handle != null)
|
||||||
|
{
|
||||||
|
Handle.Release();
|
||||||
|
Handle = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 销毁面板对象
|
||||||
|
if (_panel != null)
|
||||||
|
{
|
||||||
|
OnDestroy();
|
||||||
|
Object.Destroy(_panel);
|
||||||
|
_panel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Handle_Completed(AssetOperationHandle handle)
|
||||||
|
{
|
||||||
|
if (handle.AssetObject == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实例化对象
|
||||||
|
_panel = handle.InstantiateSync(UIComponent.UIRootStatic);
|
||||||
|
_panel.transform.localPosition = Vector3.zero;
|
||||||
|
|
||||||
|
// 获取组件
|
||||||
|
_canvas = _panel.GetComponent<Canvas>();
|
||||||
|
if (_canvas == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Not found {nameof(Canvas)} in panel {WindowName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
_canvas.overrideSorting = true;
|
||||||
|
_canvas.sortingOrder = 0;
|
||||||
|
_canvas.sortingLayerName = "Default";
|
||||||
|
|
||||||
|
// 获取组件
|
||||||
|
_raycaster = _panel.GetComponent<GraphicRaycaster>();
|
||||||
|
_childCanvas = _panel.GetComponentsInChildren<Canvas>(true);
|
||||||
|
_childRaycaster = _panel.GetComponentsInChildren<GraphicRaycaster>(true);
|
||||||
|
|
||||||
|
// 通知UI管理器
|
||||||
|
IsPrepare = true;
|
||||||
|
_prepareCallback?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region FindChildComponent
|
||||||
|
|
||||||
|
public Transform FindChild(string path)
|
||||||
|
{
|
||||||
|
return DUnityUtil.FindChild(transform, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transform FindChild(Transform trans, string path)
|
||||||
|
{
|
||||||
|
return DUnityUtil.FindChild(trans, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T FindChildComponent<T>(string path) where T : Component
|
||||||
|
{
|
||||||
|
return DUnityUtil.FindChildComponent<T>(transform, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T FindChildComponent<T>(Transform trans, string path) where T : Component
|
||||||
|
{
|
||||||
|
return DUnityUtil.FindChildComponent<T>(trans, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region UIEvent
|
||||||
|
|
||||||
|
private GameEventMgr _eventMgr;
|
||||||
|
|
||||||
|
protected GameEventMgr EventMgr
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_eventMgr == null)
|
||||||
|
{
|
||||||
|
_eventMgr = MemoryPool.Acquire<GameEventMgr>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _eventMgr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddUIEvent(int eventType, Action handler)
|
||||||
|
{
|
||||||
|
EventMgr.AddUIEvent(eventType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AddUIEvent<T>(int eventType, Action<T> handler)
|
||||||
|
{
|
||||||
|
EventMgr.AddUIEvent(eventType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AddUIEvent<T, U>(int eventType, Action<T, U> handler)
|
||||||
|
{
|
||||||
|
EventMgr.AddUIEvent(eventType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AddUIEvent<T, U, V>(int eventType, Action<T, U, V> handler)
|
||||||
|
{
|
||||||
|
EventMgr.AddUIEvent(eventType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AddUIEvent<T, U, V, W>(int eventType, Action<T, U, V, W> handler)
|
||||||
|
{
|
||||||
|
EventMgr.AddUIEvent(eventType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveAllUIEvent()
|
||||||
|
{
|
||||||
|
if (_eventMgr != null)
|
||||||
|
{
|
||||||
|
MemoryPool.Release(_eventMgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user