using UnityEngine; using UnityEngine.UI; using BaseGames.Core; namespace BaseGames.UI { /// /// 将 .Current.UIScale 应用到挂载的 /// 。挂在每个根 Canvas 上即可。 /// /// 实现要点: /// · 记录 Inspector 初始的 scaleFactor / referenceResolution 作为基准值, /// 避免反复缩放导致的累积漂移; /// · 订阅 在玩家调整后即时刷新; /// · 兼容 与 /// 两种模式。 /// [DisallowMultipleComponent] [RequireComponent(typeof(CanvasScaler))] public class UIScaleApplier : MonoBehaviour { private CanvasScaler _scaler; private float _baseScaleFactor; private Vector2 _baseReferenceResolution; private void Awake() { _scaler = GetComponent(); _baseScaleFactor = _scaler.scaleFactor; _baseReferenceResolution = _scaler.referenceResolution; } private void OnEnable() { SettingsManager.SettingsChanged += OnSettingsChanged; Apply(); } private void OnDisable() { SettingsManager.SettingsChanged -= OnSettingsChanged; } private void OnSettingsChanged(GlobalSettingsData _) => Apply(); private void Apply() { var svc = ServiceLocator.GetOrDefault(); float ui = svc?.Current?.UIScale ?? 1f; if (ui <= 0f) ui = 1f; switch (_scaler.uiScaleMode) { case CanvasScaler.ScaleMode.ConstantPixelSize: _scaler.scaleFactor = _baseScaleFactor * ui; break; case CanvasScaler.ScaleMode.ScaleWithScreenSize: // 缩小参考分辨率 → 等价于放大 UI。 _scaler.referenceResolution = _baseReferenceResolution / ui; break; default: _scaler.scaleFactor = _baseScaleFactor * ui; break; } } } }