Files
zeling_v2/Assets/_Game/Scripts/UI/Menus/DataDrivenPauseMenuController.cs
2026-06-07 11:49:55 +08:00

103 lines
4.2 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.Collections.Generic;
using UnityEngine;
using BaseGames.Core.Assets;
using BaseGames.Core.Events;
using BaseGames.UI.MainMenu; // 复用通用菜单按钮视图 MainMenuButtonView
namespace BaseGames.UI
{
/// <summary>
/// 数据驱动暂停菜单(仿 <see cref="MainMenu.DataDrivenMainMenuController"/>)。
/// 据 <see cref="PauseMenuConfigSO"/> 在运行时生成按钮、派发动作;生命周期/焦点/淡入由 <see cref="UIPanelBase"/> 统一处理。
/// 策划改 UI_PauseMenuConfig 即可增删/重排/改标签/改动作,零代码;样式改 UI_PauseScreen / UI_MainMenu_Button 预制件。
/// </summary>
public class DataDrivenPauseMenuController : UIPanelBase
{
[Header("数据表 / 按钮列表")]
[SerializeField] private PauseMenuConfigSO _config;
[Tooltip("按钮的父节点(通常挂 VerticalLayoutGroup。")]
[SerializeField] private Transform _container;
[SerializeField] private MainMenuButtonView _buttonPrefab;
[Header("Event Channels")]
[SerializeField] private VoidEventChannelSO _onResumeRequested;
[SerializeField] private SceneLoadRequestEventChannelSO _onSceneLoadRequest;
private IUIManager _uiManager;
private readonly List<MainMenuButtonView> _buttons = new();
private MainMenuButtonView _firstButton;
// 暂停面板由 UIManager 开启,此时 ServiceLocator 已就绪
protected override void OnPanelOpen()
{
_uiManager = GetService<IUIManager>();
BuildMenu();
}
protected override void OnPanelClose() => _uiManager = null;
/// <summary>默认焦点 / 焦点恢复回到首个按钮。</summary>
protected override GameObject ResolveFirstSelected()
=> _firstButton != null ? _firstButton.Button.gameObject : null;
/// <summary>据配置重建按钮列表public 以便编辑器预览/测试)。</summary>
public void BuildMenu()
{
ClearMenu();
if (_config == null || _container == null || _buttonPrefab == null) return;
foreach (var item in _config.Items)
{
var view = Instantiate(_buttonPrefab, _container);
view.gameObject.SetActive(true);
var captured = item;
view.Bind(item.labelKey, item.icon, () => Dispatch(captured));
_buttons.Add(view);
if (_firstButton == null) _firstButton = view;
}
}
private void ClearMenu()
{
_buttons.Clear();
_firstButton = null;
if (_container == null) return;
for (int i = _container.childCount - 1; i >= 0; i--)
{
var child = _container.GetChild(i).gameObject;
if (Application.isPlaying) Destroy(child);
else DestroyImmediate(child);
}
}
// ── 动作派发 ──────────────────────────────────────────────────────────
private void Dispatch(PauseMenuConfigSO.Item item)
{
switch (item.action)
{
case PauseMenuAction.Resume:
_onResumeRequested?.Raise();
_uiManager?.CloseTopPanel();
break;
case PauseMenuAction.OpenSettings:
_uiManager?.OpenPanel(PanelId.Settings);
break;
case PauseMenuAction.ReturnToMainMenu:
_uiManager?.CloseTopPanel();
_onSceneLoadRequest?.Raise(new SceneLoadRequest
{
SceneName = string.IsNullOrEmpty(item.sceneKey) ? AddressKeys.SceneMainMenu : item.sceneKey,
TransitionType = TransitionType.Scene,
});
break;
case PauseMenuAction.Quit:
Application.Quit();
break;
case PauseMenuAction.RaiseEvent:
item.eventChannel?.Raise();
break;
}
}
}
}