2025-09-22 17:45:42 +08:00
|
|
|
|
using Cysharp.Threading.Tasks;
|
2025-09-04 12:16:08 +08:00
|
|
|
|
using DG.Tweening;
|
|
|
|
|
|
using Framework;
|
|
|
|
|
|
using PhxhSDK;
|
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
2025-09-13 13:34:56 +08:00
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
public abstract partial class UIWindow
|
|
|
|
|
|
{
|
2025-09-10 16:05:21 +08:00
|
|
|
|
/*
|
2025-12-29 14:43:15 +08:00
|
|
|
|
╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|
|
|
|
|
║ UIWindow 生命周期 (Lifecycle) ║
|
|
|
|
|
|
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
|
|
|
|
|
|
║ ║
|
|
|
|
|
|
║ 【生命周期流程】 ║
|
|
|
|
|
|
║ 1. Load → UIManager.CreateWindow() 加载预制体 ║
|
2025-12-30 14:36:01 +08:00
|
|
|
|
║ 2. Init → Init() 初始化UI组件 ║
|
2025-12-29 14:43:15 +08:00
|
|
|
|
║ 3. Show → ShowWindow(data) 显示窗口 ║
|
2025-12-30 15:48:15 +08:00
|
|
|
|
║ 4. Update → Update(dt) 显示的界面每帧更新 ║
|
2025-12-29 14:43:15 +08:00
|
|
|
|
║ 5. Refresh → Refresh(data) 刷新数据 ║
|
|
|
|
|
|
║ 6. Close → CloseWindow(false) 关闭窗口(保留内存) ║
|
|
|
|
|
|
║ 7. Destroy → CloseWindow(true) 销毁窗口(释放资源) ║
|
|
|
|
|
|
║ ║
|
|
|
|
|
|
║ 【核心虚方法】(子类可重写) ║
|
|
|
|
|
|
║ • OnInit() - 初始化UI组件,绑定事件 ║
|
|
|
|
|
|
║ • OnBeforeShow() - 显示前验证,返回false取消显示 ║
|
|
|
|
|
|
║ • OnAfterShow() - 显示后处理,播放动画 ║
|
2025-12-30 15:48:15 +08:00
|
|
|
|
║ • OnUpdate(dt) - 显示的界面每帧更新(避免重度计算) ║
|
2025-12-29 14:43:15 +08:00
|
|
|
|
║ • OnRefresh() - 刷新显示内容 ║
|
|
|
|
|
|
║ • OnHide() - 隐藏时清理,暂停逻辑 ║
|
|
|
|
|
|
║ • OnRelease() - 销毁时释放资源(重要:防止内存泄漏) ║
|
|
|
|
|
|
║ ║
|
|
|
|
|
|
║ 【注意事项】 ║
|
|
|
|
|
|
║ ⚠️ 不要重写公共接口方法(Init, ShowWindow, Update等) ║
|
|
|
|
|
|
║ ⚠️ 不要直接调用OnXxx虚方法,必须通过公共接口 ║
|
|
|
|
|
|
║ ⚠️ CloseWindow(true)销毁窗口,CloseWindow(false)仅隐藏 ║
|
|
|
|
|
|
║ ║
|
|
|
|
|
|
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
|
2025-09-10 16:05:21 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
#region Lifecycle Management
|
2025-09-10 21:02:34 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 初始化窗口
|
|
|
|
|
|
/// </summary>
|
2025-12-30 14:36:01 +08:00
|
|
|
|
public void Init()
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-09-13 13:34:56 +08:00
|
|
|
|
try
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-09-13 13:34:56 +08:00
|
|
|
|
if (isInited)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning("window : {0} already inited", WindowName);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DoInit();
|
|
|
|
|
|
OnInit();
|
|
|
|
|
|
isInited = true;
|
|
|
|
|
|
}
|
2025-09-10 16:05:21 +08:00
|
|
|
|
}
|
2025-09-13 13:34:56 +08:00
|
|
|
|
catch (System.Exception e)
|
2025-09-10 16:05:21 +08:00
|
|
|
|
{
|
2025-11-04 16:08:13 +08:00
|
|
|
|
DebugUtil.LogError("window : {0} init window error: {1}\n===Stack===\n{2}\n======", WindowName, e.Message, e.StackTrace);
|
2025-09-04 12:16:08 +08:00
|
|
|
|
}
|
2025-09-13 13:34:56 +08:00
|
|
|
|
|
2025-09-10 16:05:21 +08:00
|
|
|
|
}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 显示窗口
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void ShowWindow(object data = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_isShow)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning("window : {0} is show, can't show again", WindowName);
|
|
|
|
|
|
}
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
if (!OnBeforeShow(data))
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError("window : {0} on before show return false", WindowName);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
DoShow();
|
|
|
|
|
|
OnShow(data);
|
2025-09-13 16:51:11 +08:00
|
|
|
|
if (gameObject is null)
|
2025-09-12 15:18:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.Log("UI已被销毁:{0}", WindowName);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
gameObject.SetActive(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
_isShow = true;
|
2026-01-06 16:45:21 +08:00
|
|
|
|
_isPaused = false; // 新窗口默认是活跃状态(未暂停)
|
2025-12-29 19:18:24 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-12-25 20:33:19 +08:00
|
|
|
|
OnAfterShow(data);
|
2025-09-22 17:45:42 +08:00
|
|
|
|
bool isShowOpenAnim = IsShowOpenAnim;
|
|
|
|
|
|
if (isShowOpenAnim)
|
|
|
|
|
|
{
|
2025-12-25 20:33:19 +08:00
|
|
|
|
|
2025-09-22 17:45:42 +08:00
|
|
|
|
AnimShow(() =>
|
|
|
|
|
|
{
|
2025-12-25 20:33:19 +08:00
|
|
|
|
//TODO
|
2025-09-22 17:45:42 +08:00
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.UIOpen, WindowName);
|
|
|
|
|
|
}).Forget();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-12-25 20:33:19 +08:00
|
|
|
|
//OnAfterShow(data);
|
2025-09-22 17:45:42 +08:00
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.UIOpen, WindowName);
|
|
|
|
|
|
}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
|
{
|
2025-11-04 16:08:13 +08:00
|
|
|
|
DebugUtil.LogError("window : {0} show window error: {1}\n===Stack===\n{2}\n======", WindowName, e.Message, e.StackTrace);
|
2025-09-12 15:18:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-25 15:01:35 +08:00
|
|
|
|
/// <summary>
|
2025-12-29 14:43:15 +08:00
|
|
|
|
/// 在显示前截图(如果需要)
|
2025-12-25 15:01:35 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void CaptureScreenshotIfNeeded()
|
|
|
|
|
|
{
|
|
|
|
|
|
var config = UIManager.Instance.GetWindowInfo(WindowName);
|
|
|
|
|
|
if (config.NeedScreenshot)
|
|
|
|
|
|
{
|
2025-12-29 18:41:38 +08:00
|
|
|
|
var oldActive = gameObject.activeSelf;
|
|
|
|
|
|
gameObject.SetActive(false);
|
2025-12-25 15:01:35 +08:00
|
|
|
|
ScreenshotManager.Instance.CaptureScreenshot();
|
2025-12-29 18:41:38 +08:00
|
|
|
|
gameObject.SetActive(oldActive);
|
2025-12-25 15:01:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-12-29 14:43:15 +08:00
|
|
|
|
/// 自动设置模糊背景(如果需要)
|
2025-12-25 15:01:35 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void SetupBlurBackgroundIfNeeded()
|
|
|
|
|
|
{
|
|
|
|
|
|
var config = UIManager.Instance.GetWindowInfo(WindowName);
|
|
|
|
|
|
if (!config.NeedScreenshot) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 查找约定的 GaussianBlurMask 节点
|
|
|
|
|
|
var blurTransform = transform.Find("GaussianBlurMask");
|
|
|
|
|
|
if (blurTransform != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var blurMask = blurTransform.GetComponent<UnityEngine.UI.RawImage>();
|
|
|
|
|
|
if (blurMask != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
blurMask.texture = ScreenshotManager.Instance.GetScreenTexture2D();
|
|
|
|
|
|
blurMask.gameObject.SetActive(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-10 21:02:34 +08:00
|
|
|
|
/// <summary>
|
2025-12-29 18:41:38 +08:00
|
|
|
|
/// 更新入口,界面打开的时候更新
|
2025-09-10 21:02:34 +08:00
|
|
|
|
/// </summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
public void Update(float dt)
|
2025-09-10 16:05:21 +08:00
|
|
|
|
{
|
2025-09-13 13:34:56 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
_notchScreenAdapter?.UpdateCheck();
|
|
|
|
|
|
OnUpdate(dt);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
|
{
|
2025-11-04 16:08:13 +08:00
|
|
|
|
DebugUtil.LogError("window : {0} update window error: {1}\n===Stack===\n{2}\n======", WindowName, e.Message, e.StackTrace);
|
2025-09-13 13:34:56 +08:00
|
|
|
|
}
|
2025-09-04 12:16:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
2025-09-10 21:02:34 +08:00
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// 刷新窗口数据
|
2025-09-10 21:02:34 +08:00
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
public void Refresh(object data)
|
2025-09-10 21:02:34 +08:00
|
|
|
|
{
|
2025-09-13 13:34:56 +08:00
|
|
|
|
try
|
2025-09-10 21:02:34 +08:00
|
|
|
|
{
|
2025-09-13 13:34:56 +08:00
|
|
|
|
if (isInited)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnRefresh(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError("window : {0} not inited", WindowName);
|
|
|
|
|
|
}
|
2025-09-10 21:02:34 +08:00
|
|
|
|
}
|
2025-09-13 13:34:56 +08:00
|
|
|
|
catch (System.Exception e)
|
2025-09-10 21:02:34 +08:00
|
|
|
|
{
|
2025-11-04 16:08:13 +08:00
|
|
|
|
DebugUtil.LogError("window : {0} refresh with data error: {1}\n===Stack===\n{2}\n======", WindowName, e.Message, e.StackTrace);
|
2025-09-10 21:02:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-11 21:06:09 +08:00
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// <summary>
|
2025-12-23 19:28:45 +08:00
|
|
|
|
/// 关闭窗口
|
2025-12-29 14:43:15 +08:00
|
|
|
|
/// destroy = false: 关闭但保留内存(快速重开)
|
|
|
|
|
|
/// destroy = true: 销毁并释放资源
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// </summary>
|
2025-12-23 19:28:45 +08:00
|
|
|
|
public async void CloseWindow(bool destroy)
|
2025-09-12 15:18:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
// 如果窗口已关闭
|
|
|
|
|
|
if (!_isShow)
|
2025-09-12 15:18:50 +08:00
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
// 如果不需要销毁,直接返回
|
|
|
|
|
|
if (!destroy)
|
2025-09-12 15:18:50 +08:00
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
DebugUtil.LogWarning("window : {0} is already closed", WindowName);
|
|
|
|
|
|
return;
|
2025-09-12 15:18:50 +08:00
|
|
|
|
}
|
2025-12-23 19:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果需要销毁,跳过关闭逻辑,直接执行销毁
|
|
|
|
|
|
DebugUtil.LogG($"窗口已关闭,直接销毁UI:{WindowName}");
|
|
|
|
|
|
IsClosing = true;
|
|
|
|
|
|
UIManager.Instance.RemoveWindow(mWindowName);
|
|
|
|
|
|
DoDestroy();
|
|
|
|
|
|
IsClosing = false;
|
|
|
|
|
|
return;
|
2025-09-12 15:18:50 +08:00
|
|
|
|
}
|
2025-12-23 19:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
IsClosing = true;
|
|
|
|
|
|
|
2025-12-29 19:18:24 +08:00
|
|
|
|
// 1. 获取窗口配置
|
2025-12-23 19:28:45 +08:00
|
|
|
|
var config = UIManager.Instance.GetWindowInfo(WindowName);
|
|
|
|
|
|
|
2025-12-29 19:18:24 +08:00
|
|
|
|
// 2. 可见性管理(由 UIWindowVisibilityManager 根据配置决定是否处理)
|
2025-12-23 19:28:45 +08:00
|
|
|
|
UIWindowVisibilityManager.Instance.HandleVisibilityOnClose(this, config.VisibilityStrategy);
|
|
|
|
|
|
|
2025-12-29 19:18:24 +08:00
|
|
|
|
// 3. 相机管理(在可见性管理之后处理)
|
|
|
|
|
|
UIWindowCameraManager.Instance.HandleCameraOnClose(this);
|
|
|
|
|
|
|
2025-12-25 20:26:05 +08:00
|
|
|
|
// 4. 隐藏逻辑
|
2025-09-12 15:18:50 +08:00
|
|
|
|
OnHide();
|
|
|
|
|
|
gameObject?.SetActive(false);
|
|
|
|
|
|
_isShow = false;
|
2026-01-06 16:45:21 +08:00
|
|
|
|
_isPaused = false; // 重置暂停状态
|
2025-09-12 15:18:50 +08:00
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.UIHide, WindowName);
|
2025-12-23 13:05:47 +08:00
|
|
|
|
|
2025-12-25 20:26:05 +08:00
|
|
|
|
// 5. 播放关闭动画
|
2025-12-23 19:28:45 +08:00
|
|
|
|
bool isShowCloseAnim = IsShowOpenAnim;
|
|
|
|
|
|
if (isShowCloseAnim)
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
UIManager.Instance.BlockUIForCloseOperation();
|
|
|
|
|
|
await AnimHide(() =>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
// 动画播放完毕后的回调
|
|
|
|
|
|
if (destroy)
|
2025-12-23 13:05:47 +08:00
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
DoDestroy();
|
2025-09-13 13:34:56 +08:00
|
|
|
|
UIManager.Instance.RemoveWindow(mWindowName);
|
2025-12-23 19:28:45 +08:00
|
|
|
|
}
|
2025-09-04 12:16:08 +08:00
|
|
|
|
IsClosing = false;
|
2025-12-23 19:28:45 +08:00
|
|
|
|
});
|
2025-09-04 12:16:08 +08:00
|
|
|
|
}
|
2025-12-23 19:28:45 +08:00
|
|
|
|
else
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
// 7. 如果需要销毁(无动画情况)
|
|
|
|
|
|
if (destroy)
|
|
|
|
|
|
{
|
|
|
|
|
|
DoDestroy();
|
|
|
|
|
|
UIManager.Instance.RemoveWindow(mWindowName);
|
|
|
|
|
|
}
|
2025-09-04 12:16:08 +08:00
|
|
|
|
IsClosing = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-13 13:34:56 +08:00
|
|
|
|
catch (System.Exception e)
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-11-04 16:08:13 +08:00
|
|
|
|
DebugUtil.LogError("window : {0} close window error: {1}\n===Stack===\n{2}\n======", WindowName, e.Message, e.StackTrace);
|
2025-09-04 12:16:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-23 19:28:45 +08:00
|
|
|
|
|
2026-01-06 16:52:28 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 暂停窗口
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 功能:
|
|
|
|
|
|
/// - 标记窗口为暂停状态
|
|
|
|
|
|
/// - 调用 OnPause 回调
|
|
|
|
|
|
/// - 可选:隐藏渲染(通过 hideRendering 参数控制)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 调用场景:
|
|
|
|
|
|
/// - 自动调用:窗口被遮挡时(由 UIWindowVisibilityManager 触发)
|
|
|
|
|
|
/// - 手动调用:游戏暂停、广告弹出等特殊场景
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 示例:
|
|
|
|
|
|
/// battleUI.PauseWindow(hideRendering: false); // 暂停逻辑但保持显示
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="hideRendering">是否同时隐藏渲染(SetActive(false))</param>
|
|
|
|
|
|
public void PauseWindow(bool hideRendering = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 状态检查
|
|
|
|
|
|
if (!_isShow)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning($"[UIWindow] PauseWindow failed: window is not showing ({WindowName})");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_isPaused)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning($"[UIWindow] PauseWindow ignored: already paused ({WindowName})");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_isPaused = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 调用子类的暂停逻辑
|
|
|
|
|
|
OnPause();
|
|
|
|
|
|
|
|
|
|
|
|
// 可选:隐藏渲染
|
|
|
|
|
|
if (hideRendering && gameObject != null && gameObject.activeSelf)
|
|
|
|
|
|
{
|
|
|
|
|
|
gameObject.SetActive(false);
|
|
|
|
|
|
DebugUtil.Log($"[UIWindow] Paused (hidden): {WindowName}");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.Log($"[UIWindow] Paused (logic only): {WindowName}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 恢复窗口
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 功能:
|
|
|
|
|
|
/// - 标记窗口为活跃状态
|
|
|
|
|
|
/// - 调用 OnResume 回调
|
|
|
|
|
|
/// - 可选:显示渲染(通过 showRendering 参数控制)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 调用场景:
|
|
|
|
|
|
/// - 自动调用:窗口重新显示时(由 UIWindowVisibilityManager 触发)
|
|
|
|
|
|
/// - 手动调用:游戏恢复、广告关闭等特殊场景
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 示例:
|
|
|
|
|
|
/// battleUI.ResumeWindow(showRendering: true); // 恢复逻辑并显示
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="showRendering">是否同时显示渲染(SetActive(true))</param>
|
|
|
|
|
|
public void ResumeWindow(bool showRendering = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 状态检查
|
|
|
|
|
|
if (!_isShow)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning($"[UIWindow] ResumeWindow failed: window is not showing ({WindowName})");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!_isPaused)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogWarning($"[UIWindow] ResumeWindow ignored: not paused ({WindowName})");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_isPaused = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 可选:显示渲染
|
|
|
|
|
|
if (showRendering && gameObject != null && !gameObject.activeSelf)
|
|
|
|
|
|
{
|
|
|
|
|
|
gameObject.SetActive(true);
|
|
|
|
|
|
DebugUtil.Log($"[UIWindow] Resumed (shown): {WindowName}");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.Log($"[UIWindow] Resumed (logic only): {WindowName}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 调用子类的恢复逻辑
|
|
|
|
|
|
OnResume();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-10 21:02:34 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-26 12:16:37 +08:00
|
|
|
|
#region User Interaction
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2025-12-29 14:43:15 +08:00
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
#region Internal Implementation
|
|
|
|
|
|
|
2025-12-23 19:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-12-29 19:18:24 +08:00
|
|
|
|
/// 恢复主相机状态(已废弃,由 UIWindowCameraManager 统一管理)
|
2025-12-23 19:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-12-29 19:18:24 +08:00
|
|
|
|
[System.Obsolete("RestoreMainCamera已废弃,相机状态由 UIWindowCameraManager 统一管理")]
|
2025-12-23 19:28:45 +08:00
|
|
|
|
private void RestoreMainCamera()
|
|
|
|
|
|
{
|
2025-12-29 19:18:24 +08:00
|
|
|
|
// 相机管理逻辑已移至 UIWindowCameraManager.HandleCameraOnClose
|
|
|
|
|
|
// 保留此方法以防止破坏性更改
|
2025-12-23 19:28:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 执行基础初始化
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void DoInit()
|
|
|
|
|
|
{
|
|
|
|
|
|
_isShow = false;
|
2025-12-26 17:02:41 +08:00
|
|
|
|
var metaInfo = UIManager.Instance.GetWindowInfo(WindowName);
|
|
|
|
|
|
IsShowOpenAnim = metaInfo.IsAutoAnim;
|
|
|
|
|
|
BackStrategy = UIBackStrategyFactory.CreateStrategy(metaInfo.BackStrategyType);
|
2025-09-12 15:18:50 +08:00
|
|
|
|
AutoBindField();
|
|
|
|
|
|
InitScreenAdaption();
|
2025-12-27 16:34:21 +08:00
|
|
|
|
BindDefaultCloseButtons();
|
|
|
|
|
|
BindDefaultHomeButtons();
|
|
|
|
|
|
BindDefaultBackButtons();
|
2025-09-12 15:18:50 +08:00
|
|
|
|
}
|
2025-09-10 21:02:34 +08:00
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// 执行显示逻辑
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-10 19:54:45 +08:00
|
|
|
|
private void DoShow()
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-12-29 19:18:24 +08:00
|
|
|
|
// 🎯 在显示前截图(如果需要)
|
|
|
|
|
|
CaptureScreenshotIfNeeded();
|
|
|
|
|
|
// 🎯 自动设置模糊背景(如果需要)
|
|
|
|
|
|
SetupBlurBackgroundIfNeeded();
|
|
|
|
|
|
// 🎯 相机管理(在窗口显示后处理)
|
|
|
|
|
|
var config = UIManager.Instance.GetWindowInfo(WindowName);
|
|
|
|
|
|
UIWindowVisibilityManager.Instance.HandleVisibilityOnOpen(this, config.VisibilityStrategy);
|
|
|
|
|
|
UIWindowCameraManager.Instance.HandleCameraOnOpen(this);
|
2025-09-04 12:16:08 +08:00
|
|
|
|
}
|
2025-12-29 14:43:15 +08:00
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// <summary>
|
2025-12-29 14:43:15 +08:00
|
|
|
|
/// 执行销毁逻辑
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-12-23 19:28:45 +08:00
|
|
|
|
private void DoDestroy()
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-12-23 19:28:45 +08:00
|
|
|
|
DebugUtil.LogG($"DoDestroy:{WindowName}");
|
|
|
|
|
|
|
|
|
|
|
|
// 如果窗口还在显示状态,先调用 OnHide
|
|
|
|
|
|
if (_isShow)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnHide();
|
|
|
|
|
|
_isShow = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 确保 GameObject 隐藏
|
|
|
|
|
|
if (gameObject != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
gameObject.SetActive(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送隐藏事件
|
2025-09-12 16:28:11 +08:00
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.UIHide, WindowName);
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
2025-12-23 19:28:45 +08:00
|
|
|
|
// 资源释放
|
2025-09-04 12:16:08 +08:00
|
|
|
|
if (gameObject)
|
|
|
|
|
|
{
|
2025-09-09 20:26:41 +08:00
|
|
|
|
if (isInited)
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
OnRelease();
|
2025-09-12 15:18:50 +08:00
|
|
|
|
DoRelease();
|
2025-09-09 20:26:41 +08:00
|
|
|
|
isInited = false;
|
2025-09-04 12:16:08 +08:00
|
|
|
|
}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
if (UIManager.Instance.UIWindowObjDic.ContainsKey(gameObject))
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
|
|
|
|
|
UIManager.Instance.UIWindowObjDic.Remove(gameObject);
|
|
|
|
|
|
}
|
|
|
|
|
|
UnityEngine.Object.Destroy(gameObject);
|
|
|
|
|
|
}
|
2025-12-23 19:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
// 卸载资源
|
2025-09-04 12:16:08 +08:00
|
|
|
|
AssetManager.Instance.Unload(string.Format(UIManager.UI_PREFAB_PATH, mWindowName), true);
|
|
|
|
|
|
gameObject = null;
|
|
|
|
|
|
}
|
2025-09-10 19:54:45 +08:00
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// 基础资源释放
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
private void DoRelease()
|
2025-09-04 12:16:08 +08:00
|
|
|
|
{
|
2025-09-12 15:18:50 +08:00
|
|
|
|
EventManager.Instance.Send(EventManager.EventName.UIDestroy, WindowName);
|
2025-09-12 10:54:10 +08:00
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
UnLoad();
|
|
|
|
|
|
_openAnimSeq?.Kill();
|
|
|
|
|
|
|
|
|
|
|
|
_assetReferenceManager?.Dispose();
|
|
|
|
|
|
_assetReferenceManager = null;
|
|
|
|
|
|
|
|
|
|
|
|
_notchScreenAdapter = null;
|
|
|
|
|
|
_graphicRaycasterManager = null;
|
2025-09-04 12:16:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Virtual Methods
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
// Init Phase
|
2025-12-30 14:36:01 +08:00
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// UI初始化
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void OnInit(){}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 自动绑定字段
|
|
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void AutoBindField(){}
|
2025-09-11 16:51:41 +08:00
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
// Show Phase
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-12-29 14:43:15 +08:00
|
|
|
|
/// 显示前检查(返回false可取消显示)
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// </summary>
|
2025-09-12 10:54:10 +08:00
|
|
|
|
protected virtual bool OnBeforeShow(object data)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-11 16:39:35 +08:00
|
|
|
|
/// <summary>
|
2025-12-29 14:43:15 +08:00
|
|
|
|
/// 显示时处理(已废弃,建议使用OnAfterShow)
|
2025-09-11 16:39:35 +08:00
|
|
|
|
/// </summary>
|
2025-09-24 20:46:04 +08:00
|
|
|
|
[System.Obsolete("OnShow已废弃,请使用OnAfterShow方法替代。OnAfterShow在窗口完全显示后调用,提供更稳定的显示时机。")]
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void OnShow(object data){}
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// 显示后处理
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void OnAfterShow(object data){}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-12-30 15:48:15 +08:00
|
|
|
|
/// IsShow的界面每帧更新
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void OnUpdate(float dt){}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
|
|
|
|
|
// Refresh Phase
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// 数据刷新
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void OnRefresh(object data) {}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
|
|
|
|
|
// Hide Phase
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// 隐藏时处理
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void OnHide(){}
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
2026-01-06 16:52:28 +08:00
|
|
|
|
// Pause/Resume Phase
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 窗口暂停回调(子类重写)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 调用时机:
|
|
|
|
|
|
/// - 自动调用:窗口被遮挡时(UIWindowVisibilityManager 触发)
|
|
|
|
|
|
/// - 手动调用:调用 PauseWindow() 时
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 建议处理:
|
|
|
|
|
|
/// - 停止播放背景音乐/音效
|
|
|
|
|
|
/// - 暂停动画/粒子特效
|
|
|
|
|
|
/// - 暂停定时器/倒计时
|
|
|
|
|
|
/// - 暂停网络轮询(可选)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 示例:
|
|
|
|
|
|
/// <code>
|
|
|
|
|
|
/// protected override void OnPause()
|
|
|
|
|
|
/// {
|
|
|
|
|
|
/// if (_bgmHandle != -1)
|
|
|
|
|
|
/// AudioManager.Instance.PauseBGM(_bgmHandle);
|
|
|
|
|
|
/// }
|
|
|
|
|
|
/// </code>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected virtual void OnPause() { }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 窗口恢复回调(子类重写)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 调用时机:
|
|
|
|
|
|
/// - 自动调用:窗口重新显示时(UIWindowVisibilityManager 触发)
|
|
|
|
|
|
/// - 手动调用:调用 ResumeWindow() 时
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 建议处理:
|
|
|
|
|
|
/// - 恢复播放背景音乐/音效
|
|
|
|
|
|
/// - 恢复动画/粒子特效
|
|
|
|
|
|
/// - 恢复定时器/倒计时
|
|
|
|
|
|
/// - 刷新数据(可选)
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 示例:
|
|
|
|
|
|
/// <code>
|
|
|
|
|
|
/// protected override void OnResume()
|
|
|
|
|
|
/// {
|
|
|
|
|
|
/// if (_bgmHandle != -1)
|
|
|
|
|
|
/// AudioManager.Instance.ResumeBGM(_bgmHandle);
|
|
|
|
|
|
/// }
|
|
|
|
|
|
/// </code>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
protected virtual void OnResume() { }
|
|
|
|
|
|
|
2025-09-12 15:18:50 +08:00
|
|
|
|
// Release Phase
|
|
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// <summary>
|
2025-09-12 15:18:50 +08:00
|
|
|
|
/// 资源释放
|
2025-09-04 12:16:08 +08:00
|
|
|
|
/// </summary>
|
2025-09-13 13:34:56 +08:00
|
|
|
|
protected virtual void OnRelease(){}
|
2025-09-12 15:18:50 +08:00
|
|
|
|
|
2025-09-04 12:16:08 +08:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|