using UnityEngine;
using BaseGames.Core;
using BaseGames.Core.Events;
// 项目内存在两份同名枚举(Core.ColorblindMode 与 Core.Events.ColorblindMode)。
// AccessibilitySettingsSO / ColorBlindFilter / ColorblindModeEventChannelSO 使用 Events 版本,
// 因此在本文件中明确以 Events 版本消歧,避免 CS0104。
using ColorblindMode = BaseGames.Core.Events.ColorblindMode;
namespace BaseGames.Support.Accessibility
{
///
/// 无障碍功能管理器(架构 16_SupportingModules §6.1)。
/// 响应设置变更,广播色盲模式事件;通过 ServiceLocator 提供 IAccessibilityService 查询接口。
///
public class AccessibilityManager : MonoBehaviour, IAccessibilityService
{
[Header("设置资产")]
[SerializeField] private AccessibilitySettingsSO _settings;
[Header("事件频道(输出)")]
[SerializeField] private ColorblindModeEventChannelSO _onColorblindModeChanged;
[SerializeField] private BoolEventChannelSO _onScreenShakeChanged;
// ── IAccessibilityService ─────────────────────────────────────────────
/// 当前设置是否允许播放屏幕震动效果。
public bool CanPlayScreenShake()
=> _settings == null || _settings.ScreenShake;
private void Awake()
{
if (ServiceLocator.GetOrDefault() != null)
{
Debug.LogWarning("[AccessibilityManager] 已存在实例,请确保本组件仅放置在 Persistent 场景中。", this);
Destroy(this);
return;
}
ServiceLocator.Register(this);
if (_settings != null)
_settings.Load();
}
private void Start()
{
// 初始化时广播当前色盲模式
if (_settings != null)
_onColorblindModeChanged?.Raise(_settings.ColorblindMode);
}
private void OnDestroy()
{
ServiceLocator.Unregister(this);
}
/// 应用新的设置并持久化。
public void Apply(AccessibilitySettingsSO newSettings)
{
_settings.ScreenShake = newSettings.ScreenShake;
_settings.ReducedFlash = newSettings.ReducedFlash;
_settings.LargeText = newSettings.LargeText;
_settings.HighContrast = newSettings.HighContrast;
_settings.UIScale = newSettings.UIScale;
bool colorblindChanged = _settings.ColorblindMode != newSettings.ColorblindMode;
_settings.ColorblindMode = newSettings.ColorblindMode;
_settings.Save();
_onScreenShakeChanged?.Raise(_settings.ScreenShake);
if (colorblindChanged)
_onColorblindModeChanged?.Raise(_settings.ColorblindMode);
}
/// 直接设置色盲模式。
public void SetColorblindMode(ColorblindMode mode)
{
if (_settings == null) return;
_settings.ColorblindMode = mode;
_settings.Save();
_onColorblindModeChanged?.Raise(mode);
}
/// 直接设置屏幕抖动开关。
public void SetScreenShake(bool enabled)
{
if (_settings == null) return;
_settings.ScreenShake = enabled;
_settings.Save();
_onScreenShakeChanged?.Raise(enabled);
}
public AccessibilitySettingsSO Settings => _settings;
}
}