DESKTOP-SAJ6RKV\Administrator 1ee51b518a 加入弹窗
2025-06-04 09:25:23 +08:00

459 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;
namespace TEngine
{
public abstract class UIWindow : UIBase
{
#region Propreties
private System.Action<UIWindow> _prepareCallback;
private bool _isCreate = false;
private GameObject _panel;
private Canvas _canvas;
protected Canvas Canvas => _canvas;
private Canvas[] _childCanvas;
private GraphicRaycaster _raycaster;
protected GraphicRaycaster GraphicRaycaster => _raycaster;
private GraphicRaycaster[] _childRaycaster;
public override UIType Type => UIType.Window;
/// <summary>
/// 窗口位置组件。
/// </summary>
public override Transform transform => _panel.transform;
/// <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 virtual bool FullScreen { private set; get; } = false;
/// <summary>
/// 是内部资源无需AB加载。
/// </summary>
public bool FromResources { private set; get; }
/// <summary>
/// 隐藏窗口关闭时间。
/// </summary>
public int HideTimeToClose { get; set; }
public int HideTimerId { get; set; }
/// <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 = false;
internal bool IsDestroyed = false;
/// <summary>
/// UI是否隐藏标志位。
/// </summary>
public bool IsHide { internal set; get; } = false;
#endregion
public void Init(string name, int layer, bool fullScreen, string assetName, bool fromResources, int hideTimeToClose)
{
WindowName = name;
WindowLayer = layer;
FullScreen = fullScreen;
AssetName = assetName;
FromResources = fromResources;
HideTimeToClose = hideTimeToClose;
}
internal void TryInvoke(System.Action<UIWindow> prepareCallback, System.Object[] userDatas)
{
CancelHideToCloseTimer();
base.userDatas = userDatas;
if (IsPrepare)
{
prepareCallback?.Invoke(this);
}
else
{
_prepareCallback = prepareCallback;
}
}
internal async UniTaskVoid InternalLoad(string location, Action<UIWindow> prepareCallback, bool isAsync, System.Object[] userDatas)
{
_prepareCallback = prepareCallback;
this.userDatas = userDatas;
if (!FromResources)
{
if (isAsync)
{
var uiInstance = await GameModule.Resource.LoadGameObjectAsync(location, parent: GameModule.UI.UIRoot);
Handle_Completed(uiInstance);
}
else
{
var uiInstance = GameModule.Resource.LoadGameObject(location, parent: GameModule.UI.UIRoot);
Handle_Completed(uiInstance);
}
}
else
{
GameObject panel = Object.Instantiate(Resources.Load<GameObject>(location), GameModule.UI.UIRoot);
Handle_Completed(panel);
}
}
internal void InternalCreate()
{
if (_isCreate == false)
{
_isCreate = true;
ScriptGenerator();
BindMemberProperty();
RegisterEvent();
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
{
// 原版这里好像是有个Bug后续细看
//listChild = listNextUpdateChild;
listChild = ListChild;
}
for (int i = 0; i < listChild.Count; i++)
{
var uiWidget = listChild[i];
if (uiWidget == null)
{
continue;
}
TProfiler.BeginSample(uiWidget.name);
var needValid = uiWidget.InternalUpdate();
TProfiler.EndSample();
if (!updateListValid && needValid)
{
listNextUpdateChild.Add(uiWidget);
}
}
if (!updateListValid)
{
m_updateListValid = true;
}
}
TProfiler.BeginSample("OnUpdate");
bool needUpdate = false;
if (listNextUpdateChild == null || listNextUpdateChild.Count <= 0)
{
HasOverrideUpdate = true;
OnUpdate();
needUpdate = HasOverrideUpdate;
}
else
{
OnUpdate();
needUpdate = true;
}
TProfiler.EndSample();
return needUpdate;
}
internal void InternalDestroy(bool isShutDown = false)
{
_isCreate = false;
RemoveAllUIEvent();
for (int i = 0; i < ListChild.Count; i++)
{
var uiChild = ListChild[i];
uiChild.CallDestroy();
uiChild.OnDestroyWidget();
}
// 注销回调函数
_prepareCallback = null;
OnDestroy();
// 销毁面板对象
if (_panel != null)
{
Object.Destroy(_panel);
_panel = null;
}
IsDestroyed = true;
if (!isShutDown)
{
CancelHideToCloseTimer();
}
}
/// <summary>
/// 处理资源加载完成回调。
/// </summary>
/// <param name="panel">面板资源实例。</param>
private void Handle_Completed(GameObject panel)
{
if (panel == null)
{
return;
}
IsLoadDone = true;
if (IsDestroyed)
{
Object.Destroy(panel);
return;
}
panel.name = GetType().Name;
_panel = panel;
_panel.transform.localPosition = Vector3.zero;
// 获取组件
_canvas = _panel.GetComponent<Canvas>();
if (_canvas == null)
{
throw new Exception($"Not found {nameof(Canvas)} in panel {WindowName} {panel.name}");
}
_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 Hide()
{
GameModule.UI.HideUI(this.GetType());
}
protected virtual void Close()
{
GameModule.UI.CloseUI(this.GetType());
}
internal void CancelHideToCloseTimer()
{
IsHide = false;
if (HideTimerId > 0)
{
GameModule.Timer.RemoveTimer(HideTimerId);
HideTimerId = 0;
}
}
}
}