68 lines
2.3 KiB
C#
68 lines
2.3 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using BaseGames.Core;
|
|
|
|
namespace BaseGames.UI
|
|
{
|
|
/// <summary>
|
|
/// 将 <see cref="ISettingsService"/>.<c>Current.UIScale</c> 应用到挂载的
|
|
/// <see cref="CanvasScaler"/>。挂在每个根 Canvas 上即可。
|
|
///
|
|
/// 实现要点:
|
|
/// · 记录 Inspector 初始的 <c>scaleFactor</c> / <c>referenceResolution</c> 作为基准值,
|
|
/// 避免反复缩放导致的累积漂移;
|
|
/// · 订阅 <see cref="SettingsManager.SettingsChanged"/> 在玩家调整后即时刷新;
|
|
/// · 兼容 <see cref="CanvasScaler.ScaleMode.ScaleWithScreenSize"/> 与
|
|
/// <see cref="CanvasScaler.ScaleMode.ConstantPixelSize"/> 两种模式。
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
[RequireComponent(typeof(CanvasScaler))]
|
|
public class UIScaleApplier : MonoBehaviour
|
|
{
|
|
private CanvasScaler _scaler;
|
|
private float _baseScaleFactor;
|
|
private Vector2 _baseReferenceResolution;
|
|
|
|
private void Awake()
|
|
{
|
|
_scaler = GetComponent<CanvasScaler>();
|
|
_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<ISettingsService>();
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|