mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
394 lines
10 KiB
C#
394 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using YooAsset;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace TEngine
|
|
{
|
|
public abstract class UIWindow : UIBase
|
|
{
|
|
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 override RectTransform rectTransform => _panel.transform as RectTransform;
|
|
|
|
/// <summary>
|
|
/// 窗口的实例资源对象。
|
|
/// </summary>
|
|
public override 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 == UIModule.WINDOW_SHOW_LAYER;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
set
|
|
{
|
|
if (_canvas != null)
|
|
{
|
|
int setLayer = value ? UIModule.WINDOW_SHOW_LAYER : UIModule.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;
|
|
|
|
public void Init(string name, int layer, bool fullScreen, string assetName)
|
|
{
|
|
WindowName = name;
|
|
WindowLayer = layer;
|
|
FullScreen = fullScreen;
|
|
AssetName = assetName;
|
|
}
|
|
|
|
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 bool InternalUpdate()
|
|
{
|
|
if (!IsPrepare ||!Visible)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
List<UIWidget> listNextUpdateChild = null;
|
|
if (ListChild != null && ListChild.Count > 0)
|
|
{
|
|
listNextUpdateChild = m_listUpdateChild;
|
|
var updateListValid = m_updateListValid;
|
|
List<UIWidget> listChild = null;
|
|
if (!updateListValid)
|
|
{
|
|
if (listNextUpdateChild == null)
|
|
{
|
|
listNextUpdateChild = new List<UIWidget>();
|
|
m_listUpdateChild = listNextUpdateChild;
|
|
}
|
|
else
|
|
{
|
|
listNextUpdateChild.Clear();
|
|
}
|
|
|
|
listChild = ListChild;
|
|
}
|
|
else
|
|
{
|
|
listChild = listNextUpdateChild;
|
|
}
|
|
|
|
for (int i = 0; i < listChild.Count; i++)
|
|
{
|
|
var uiWidget = listChild[i];
|
|
|
|
UnityEngine.Profiling.Profiler.BeginSample(uiWidget.name);
|
|
var needValid = uiWidget.InternalUpdate();
|
|
UnityEngine.Profiling.Profiler.EndSample();
|
|
|
|
if (!updateListValid && needValid)
|
|
{
|
|
listNextUpdateChild.Add(uiWidget);
|
|
}
|
|
}
|
|
|
|
if (!updateListValid)
|
|
{
|
|
m_updateListValid = true;
|
|
}
|
|
}
|
|
|
|
UnityEngine.Profiling.Profiler.BeginSample("OnUpdate");
|
|
|
|
bool needUpdate = false;
|
|
if (listNextUpdateChild == null || listNextUpdateChild.Count <= 0)
|
|
{
|
|
HasOverrideUpdate = true;
|
|
OnUpdate();
|
|
needUpdate = HasOverrideUpdate;
|
|
}
|
|
else
|
|
{
|
|
OnUpdate();
|
|
needUpdate = true;
|
|
}
|
|
UnityEngine.Profiling.Profiler.EndSample();
|
|
|
|
return needUpdate;
|
|
}
|
|
|
|
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(UIModule.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);
|
|
}
|
|
|
|
|
|
protected virtual void Close()
|
|
{
|
|
GameModule.UI.CloseWindow(this.GetType());
|
|
}
|
|
}
|
|
} |