Files
zeling_v2/Assets/_Game/Scripts/UI/Menus/SettingsPanelController.cs
2026-05-25 11:54:37 +08:00

83 lines
3.7 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 TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using BaseGames.Core;
namespace BaseGames.UI
{
/// <summary>
/// 设置面板控制器(架构 10_UIModule §7
/// 驱动 SettingsManager 的音量与画面设置,并从当前配置初始化控件值。
/// </summary>
public class SettingsPanelController : MonoBehaviour, IFocusable
{
// ISettingsService 通过 ServiceLocator 获取,无需 Inspector 直接注入具体类,
// 支持测试场景替换 Mock 实现。
private ISettingsService _settings;
[Header("音量滑条")]
[SerializeField] private Slider _masterVolume;
[SerializeField] private Slider _bgmVolume;
[SerializeField] private Slider _sfxVolume;
[SerializeField] private Slider _ambientVolume;
[Header("画面")]
[SerializeField] private Toggle _vSyncToggle;
[SerializeField] private TMP_Dropdown _fpsDropdown; // 30 / 60 / 120 / 无限
[Header("按键重绑定")]
[SerializeField] private GameObject _rebindPanelRoot; // RebindPanel GameObject
private static readonly int[] FpsOptions = { 30, 60, 120, -1 };
private void OnEnable()
{
_settings = ServiceLocator.GetOrDefault<ISettingsService>();
if (_settings == null) return;
var data = _settings.Current;
// 初始化控件值(先移除监听再设置值再添加,防止面板重开时重复注册)
InitSlider(_masterVolume, data.MasterVolume, v => _settings.SetMasterVolume(v));
InitSlider(_bgmVolume, data.BGMVolume, v => _settings.SetBGMVolume(v));
InitSlider(_sfxVolume, data.SFXVolume, v => _settings.SetSFXVolume(v));
InitSlider(_ambientVolume,data.AmbientVolume, v => _settings.SetAmbientVolume(v));
if (_vSyncToggle != null)
{
_vSyncToggle.onValueChanged.RemoveAllListeners();
_vSyncToggle.isOn = data.VSync;
_vSyncToggle.onValueChanged.AddListener(v => _settings.SetVSync(v));
}
if (_fpsDropdown != null)
{
_fpsDropdown.onValueChanged.RemoveAllListeners();
int idx = System.Array.IndexOf(FpsOptions, data.TargetFPS);
_fpsDropdown.value = idx >= 0 ? idx : 1; // default 60
_fpsDropdown.onValueChanged.AddListener(i =>
_settings.SetTargetFrameRate(FpsOptions[Mathf.Clamp(i, 0, FpsOptions.Length - 1)]));
}
// 手柄导航:打开设置面板时将焦点置于主音量滑条
EventSystem.current?.SetSelectedGameObject(_masterVolume?.gameObject);
}
// ── 辅助 ──────────────────────────────────────────────────────────────
private static void InitSlider(Slider slider, float value, UnityEngine.Events.UnityAction<float> onChange)
{
if (slider == null) return;
slider.onValueChanged.RemoveAllListeners();
slider.value = value;
slider.onValueChanged.AddListener(onChange);
}
// ── IFocusable ────────────────────────────────────────────────────────
/// <summary>面板恢复为栈顶时将焦点移回主音量滑条。</summary>
public void OnFocusRestored()
=> EventSystem.current?.SetSelectedGameObject(_masterVolume?.gameObject);
}
}