NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/UI/UIWindow.Lifecycle.cs

531 lines
32 KiB
C#
Raw Normal View History

using System;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using Framework;
using PhxhSDK;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// UI窗口基类 - 生命周期管理部分
/// 包含窗口的创建、显示、隐藏、关闭等生命周期管理功能
/// </summary>
public abstract partial class UIWindow
{
2025-09-10 16:05:21 +08:00
/*
UIWindow (Lifecycle)
1. Load -
UIRoot.CreateWindow()
GameObject
UIWindow
2. Init -
UIWindow.Init(data) // 窗口初始化(独立调用) ║
*OnBeforeInit(data) // 预处理数据 (原 PreLoad
DoInit() // 基础初始化 ║
AutoBindField() // 绑定UI组件引用 ║
InitScreenAdaption() // 屏幕适配 ║
_TryBindBgClose() // 绑定通用事件 ║
*OnInit() // 初始化UI状态设置默认值 ║
3. Show -
UIWindow.ShowWindow(data) // 显示窗口(公共接口) ║
Show(data) // 内部显示逻辑 ║
SetActive(true) // 激活GameObject ║
// 处理全屏窗口的相机逻辑 ║
2025-09-10 21:02:34 +08:00
*OnAfterShow(data) // 显示回调,业务逻辑处理 ║
2025-09-10 16:05:21 +08:00
// 根据设置播放动画 ║
// 播放默认打开音效 ║
4. Update -
2025-09-10 21:02:34 +08:00
Update(dt) -> *OnUpdate(dt) // 每帧更新处理UI逻辑合并原 Update
2025-09-10 16:05:21 +08:00
5. Refresh -
2025-09-10 21:02:34 +08:00
RefreshWithData(data) // 数据刷新(原 ReloadWindow
*OnDataRefresh(data) // 刷新UI内容更新显示数据原 OnReloadWindow
2025-09-10 16:05:21 +08:00
6. Hide -
HideWindow() -> Hide()
SetActive(false) // 隐藏GameObject ║
*OnHideWindow() // 隐藏回调 ║
7. Close -
CloseWindow() -> DestroyWindow()
*OnHideWindow() // 隐藏回调 ║
*OnRelease() // 释放资源,清理引用 ║
Destroy(gameObject) // 销毁GameObject ║
: InitShow
使: Init(data)ShowWindow(data)
:
:
- *
🔸 *OnBeforeInit(data) -
DoInitAutoBindFieldInitScreenAdaption OnInit
UI
OpenData
base.OnBeforeInit()
🔸 *OnInit() - UI
DoInit
UI
base.OnInit()
2025-09-10 21:02:34 +08:00
🔸 *OnAfterShow(data) -
2025-09-10 16:05:21 +08:00
2025-09-10 21:02:34 +08:00
base.OnAfterShow(data)
2025-09-10 16:05:21 +08:00
🔸 *OnUpdate(dt) -
🔸 *OnDataRefresh(data) -
RefreshWithData
base.OnDataRefresh(data)
🔸 *OnHideWindow() -
base.OnHideWindow()
🔸 *OnRelease() -
Tween
base.OnRelease()
AutoBindField:
RefreshWithData: OnDataRefresh
Init: OnBeforeInitDoInitOnInit
ShowWindow: Show
: InitShow
base.OnXxx()
*/
2025-09-10 21:02:34 +08:00
#region Private Helper Methods
/// <summary>
/// 尝试绑定背景关闭按钮
/// </summary>
private void _TryBindBgClose()
{
var trans = transform.Find("BgClose");
if (trans)
{
var btn = trans.GetComponent<Button>();
if (btn)
{
BindButton(btn, () =>
{
var clickAudio = btn.GetComponent<ClickAudio>();
if (clickAudio)
{
if (clickAudio.IsPlayAudio && !string.IsNullOrEmpty(clickAudio.AudioKey))
AudioManager.Instance.PlayAudio(clickAudio.AudioKey);
else
{
CommonUtilsFramework.PlayUICommonSound();
}
}
if (_onBgCloseFunc == null)
{
CloseWindow();
return;
}
_onBgCloseFunc?.Invoke();
});
}
}
}
2025-09-10 21:02:34 +08:00
#endregion
#region Core Lifecycle Methods
/// <summary>
/// 初始化窗口
/// </summary>
/// <param name="data">传入数据</param>
2025-09-10 16:05:21 +08:00
public void Init(object data = null)
{
2025-09-10 16:05:21 +08:00
OnBeforeInit(data);
if (isInited)
{
2025-09-10 16:05:21 +08:00
DebugUtil.LogWarning("window : {0} already inited", WindowName);
}
else
{
DoInit();
OnInit();
2025-09-09 20:26:41 +08:00
isInited = true;
}
2025-09-10 16:05:21 +08:00
}
2025-09-10 21:02:34 +08:00
/// <summary>
/// 执行基础初始化
/// </summary>
2025-09-10 16:05:21 +08:00
private void DoInit()
{
_isShow = false;
2025-09-10 16:05:21 +08:00
_bDoNotSetMainCamera = UIManager.Instance.GetIsNotSetCameraByPath(WindowName);
IsShowOpenAnim = UIManager.Instance.GetIsAutoPlayAnim(WindowName);
AutoBindField();
InitScreenAdaption();
_TryBindBgClose();
}
2025-09-10 21:02:34 +08:00
/// <summary>
/// 使用新数据刷新窗口内容
/// </summary>
/// <param name="data">新的数据</param>
public void RefreshWithData(object data)
{
if (isInited)
{
OnDataRefresh(data);
}
else
{
DebugUtil.LogError("window : {0} not inited", WindowName);
}
}
/// <summary>
/// 关闭窗口
/// </summary>
/// <param name="closeType">关闭类型</param>
/// <param name="forceShowAnim">强制设置动画,0不管1强制开-1强制不开</param>
/// <param name="isOpenMainCamera">是否打开主相机</param>
public async void CloseWindow(UIWindowCloseType closeType = UIWindowCloseType.HideAndDestroy, int forceShowAnim = 0,
bool isOpenMainCamera = true)
{
IsClosing = true;
DebugUtil.LogG($"关闭UI:{WindowName}, closeType{closeType}");
if (UIManager.Instance.CheckWindowIsFullScreen(this))
{
if (!_bDoNotSetMainCamera)
{
CameraManager.Instance.SetMainCameraActive(isOpenMainCamera);
}
}
if (closeType == UIWindowCloseType.HideAndDestroy)
{
var last = UIManager.Instance.GetLast();
if (last == this)
{
DebugUtil.LogG($"PopWindow{this.WindowName}");
UIManager.Instance.PopWindow();
}
bool isShowCloseAnim = IsShowOpenAnim;
if (forceShowAnim > 0)
{
isShowCloseAnim = true;
}
if (forceShowAnim < 0)
{
isShowCloseAnim = false;
}
//调试
//isShowCloseAnim = false;
_OnClose();
if (isShowCloseAnim)
{
UIManager.Instance.OnClick(true);
await AnimHide(() =>
{
DestroyWindow();
UIManager.Instance.RemoveWindow(mWindowName);
IsClosing = false;
});
}
else
{
UIManager.Instance.RemoveWindow(mWindowName);
DestroyWindow();
IsClosing = false;
}
}
else if(closeType == UIWindowCloseType.OnlyHide)
{
Hide();
IsClosing = false;
}
else if(closeType == UIWindowCloseType.HideAndPush)
{
Hide();
IsClosing = false;
//UIManager.Instance.PushWindow(this);
}
else
{
//强制清除所有界面时使用
DestroyWindow();
UIManager.Instance.RemoveWindow(mWindowName);
IsClosing = false;
}
}
2025-09-10 21:02:34 +08:00
#endregion
#region Private Internal Methods
/// <summary>
2025-09-10 21:02:34 +08:00
/// 执行实际的显示逻辑
/// </summary>
2025-09-10 19:54:45 +08:00
private void DoShow()
{
if (gameObject == null)
{
DebugUtil.Log("UI已被销毁:{0}", WindowName);
}
else
{
gameObject.SetActive(true);
}
if (UIManager.Instance.WindowInfos.TryGetValue(WindowName, out var windowInfo))
{
if (CameraManager.Instance.CheckMainCameraIsActive())
{
if (windowInfo.UIOpenType == UIOpenType.FullScreen)
{
//特殊处理主界面
if (!_bDoNotSetMainCamera && WindowName != UINameConst.UI_MainPanel)
{
CameraManager.Instance.SetMainCameraActive(false);
}
}
}
}
}
/// <summary>
/// 隐藏窗口
/// </summary>
/// <param name="isOnlyHide">是否仅隐藏</param>
private void Hide(bool isOnlyHide = false)
{
gameObject?.SetActive(false);
if (!isOnlyHide)
{
OnHideWindow();
_isShow = false;
if (UIManager.Instance.WindowInfos.TryGetValue(WindowName, out var windowInfo))
{
if (windowInfo.UIOpenType == UIOpenType.FullScreen)
{
if (!CameraManager.Instance.CheckMainCameraIsActive())
{
CameraManager.Instance.SetMainCameraActive(true);
}
}
}
}
}
/// <summary>
/// 关闭时的内部处理
/// </summary>
private void _OnClose()
{
if (UIManager.Instance.UiWindowStack.Count <= 0)
{
return;
}
if (UIManager.Instance.CheckWindowIsFullScreen(this))
{
var window = UIManager.Instance.GetLastFullScreen();
if (window != null && window != this)
{
if (UIManager.Instance.CheckIsWindowInStack(this))
{
UIManager.Instance.ForceRemoveWindow(this);
DebugUtil.LogG($"UI出栈,{WindowName}");
}
}
for (int i = UIManager.Instance.UiWindowStack.Count - 1; i >= 0; i--)
{
var latestWindow = UIManager.Instance.UiWindowStack[i];
latestWindow.ShowWindow();
if (UIManager.Instance.CheckWindowIsFullScreen(latestWindow))
break;
}
}
else
{
UIManager.Instance.ForceRemoveWindow(this);
}
}
/// <summary>
/// 销毁窗口
/// </summary>
private void DestroyWindow()
{
DebugUtil.LogG($"DestroyWindow:{WindowName}");
OnHideWindow();
if (gameObject)
{
2025-09-09 20:26:41 +08:00
if (isInited)
{
OnRelease();
2025-09-09 20:26:41 +08:00
isInited = false;
}
if(UIManager.Instance.UIWindowObjDic.ContainsKey(gameObject))
{
UIManager.Instance.UIWindowObjDic.Remove(gameObject);
}
UnityEngine.Object.Destroy(gameObject);
}
AssetManager.Instance.Unload(string.Format(UIManager.UI_PREFAB_PATH, mWindowName), true);
gameObject = null;
}
#endregion
2025-09-10 21:02:34 +08:00
#region Public Interface
/// <summary>
/// 隐藏窗口(公共接口)
/// </summary>
/// <param name="isOnlyHide">是否仅隐藏</param>
public void HideWindow(bool isOnlyHide = false)
{
Hide(isOnlyHide);
}
2025-09-10 19:54:45 +08:00
/// <summary>
/// 显示窗口(公共接口)
/// </summary>
/// <param name="data">传入数据</param>
public void ShowWindow(object data = null)
{
2025-09-10 19:54:45 +08:00
//未被唤醒不执行Show
if (IsUnEnabled)
{
return;
}
OnBeforeShow(data);
DoShow();
_isShow = true;
OnAfterShow(data);
2025-09-10 21:02:34 +08:00
EventManager.Instance.Send(EventManager.EventName.UIOpen, WindowName);
}
#endregion
2025-09-10 21:02:34 +08:00
#region Virtual Methods (Override Points)
/// <summary>
2025-09-09 20:26:41 +08:00
/// 窗口预处理钩子函数(生命周期方法)
/// 在 AutoBindField() 和 OnInit() 之前调用,用于窗口初始化前的准备工作
/// </summary>
/// <param name="data">传入数据</param>
2025-09-10 19:54:45 +08:00
protected virtual void OnBeforeInit(object data = null)
{
}
2025-09-10 21:02:34 +08:00
/// <summary>
/// 显示前钩子函数
/// 在窗口显示之前调用,用于显示前的准备工作
/// </summary>
/// <param name="data">传入数据</param>
2025-09-10 19:54:45 +08:00
protected virtual void OnBeforeShow(object data)
{
}
/// <summary>
2025-09-10 21:02:34 +08:00
/// 显示后钩子函数
/// 在窗口显示之后调用,用于显示后的业务逻辑处理
/// </summary>
/// <param name="data">传入数据</param>
2025-09-10 19:54:45 +08:00
protected virtual void OnAfterShow(object data)
{
}
/// <summary>
2025-09-10 21:02:34 +08:00
/// 隐藏窗口时调用的回调函数
/// </summary>
protected virtual void OnHideWindow()
{
EventManager.Instance.Send(EventManager.EventName.UIClose, WindowName);
}
/// <summary>
2025-09-09 20:26:41 +08:00
/// 数据刷新时调用的回调函数
/// </summary>
2025-09-09 20:26:41 +08:00
/// <param name="data">新的数据</param>
protected virtual void OnDataRefresh(object data) { }
/// <summary>
2025-09-10 21:02:34 +08:00
/// 初始化UI状态设置默认值
/// 在 DoInit基础初始化之后调用用于子类的UI初始化逻辑
/// </summary>
public virtual void OnInit(){}
/// <summary>
/// 自动绑定字段
/// </summary>
protected virtual void AutoBindField()
{
}
/// <summary>
2025-09-10 21:02:34 +08:00
/// 释放资源,取消订阅,清理引用
/// 对应OnInit在销毁界面时调用子类必须调用 base.OnRelease()
/// </summary>
public virtual void OnRelease()
{
EventManager.Instance.Send(EventManager.EventName.UIDestroy, WindowName);
UnLoad();
_openAnimSeq?.Kill();
// 清理资源引用管理器
_assetReferenceManager?.Dispose();
_assetReferenceManager = null;
// 清理刘海屏适配器
_notchScreenAdapter = null;
// 清理GraphicRaycaster管理器
_graphicRaycasterManager = null;
}
#endregion
}