UI 系统

This commit is contained in:
2026-06-08 16:05:00 +08:00
parent b582317692
commit 247de307c6
150 changed files with 10945 additions and 158 deletions

View File

@@ -27,6 +27,10 @@ namespace BaseGames.UI
private readonly List<MainMenuButtonView> _buttons = new();
private MainMenuButtonView _firstButton;
/// <summary>本面板因某个菜单动作(继续 / 返回主菜单)而关闭——它们已自行处理游戏状态,
/// OnPanelClose 不应再发恢复事件。ESC / 手柄 B 取消关闭时此标志为 false需要补发恢复。</summary>
private bool _resumeHandledByAction;
// 暂停面板由 UIManager 开启,此时 ServiceLocator 已就绪
protected override void OnPanelOpen()
{
@@ -34,7 +38,23 @@ namespace BaseGames.UI
BuildMenu();
}
protected override void OnPanelClose() => _uiManager = null;
protected override void OnPanelClose()
{
_uiManager = null;
// 被弹出栈ESC / 手柄 B 取消)关闭时也要恢复游戏:否则 GameManager 停在 Paused、
// 输入留在 UI mapGameplay 的 Pause 键被禁用,导致暂停菜单关闭后再也无法呼出。
//
// 仅在「真正出栈」时恢复——被上层面板(设置等 Replace 压栈)覆盖时本面板的 OnDisable
// 同样触发但此时本面板仍是栈顶UINavigator.Push 先停用下层再压入新面板),不应恢复。
// 区分依据:出栈时 UINavigator.Pop 已先出栈,栈顶不再是本面板;覆盖时栈顶仍是本面板。
// 「继续」「返回主菜单」已各自处理状态,由 _resumeHandledByAction 抑制重复 / 误恢复。
var nav = GetService<IUINavigator>();
bool poppedOff = nav == null || nav.Top != this;
if (poppedOff && !_resumeHandledByAction)
_onResumeRequested?.Raise();
_resumeHandledByAction = false;
}
/// <summary>默认焦点 / 焦点恢复回到首个按钮。</summary>
protected override GameObject ResolveFirstSelected()
@@ -76,6 +96,7 @@ namespace BaseGames.UI
switch (item.action)
{
case PauseMenuAction.Resume:
_resumeHandledByAction = true; // 自行发恢复,避免 OnPanelClose 重复发
_onResumeRequested?.Raise();
_uiManager?.CloseTopPanel();
break;
@@ -86,6 +107,8 @@ namespace BaseGames.UI
_uiManager?.OpenPanel(item.targetPanel);
break;
case PauseMenuAction.ReturnToMainMenu:
// 不发恢复:须保持 Paused 状态,使 SceneLoaded(MainMenu) 时 Paused→MainMenu 为合法转换。
_resumeHandledByAction = true;
_uiManager?.CloseTopPanel();
_onSceneLoadRequest?.Raise(new SceneLoadRequest
{