好多新内容
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// 让 CanvasScaler 的 matchWidthOrHeight 随屏幕宽高比动态切换,实现“设计区域永不裁切”(contain):
|
||||
/// - 屏幕比设计更宽(>16:9):锁高度(match=1),左右由背景 cover 填满,UI 不被竖向裁。
|
||||
/// - 屏幕比设计更窄(<16:9,如 16:10 / 4:3):锁宽度(match=0),上下由背景 cover 填满,UI 不被横向裁。
|
||||
/// 这样 1920x1080 设计范围内的所有 UI 在任意宽高比下都完整可见,仅“更宽松”的一侧留出由背景填充的余量。
|
||||
///
|
||||
/// 满足三要求:
|
||||
/// 1) 不改业务逻辑、不改对象引用;只调 CanvasScaler 的一个表现参数。
|
||||
/// 2) 16:9 屏下 match=1 与原状态一致,逐像素不变;只改缩放基准,不动任何锚点/位置/动画。
|
||||
/// 3) 窄屏不再裁切、宽屏铺满,配合背景 cover 始终填满屏幕。
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(CanvasScaler))]
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class UICanvasMatchFitter : MonoBehaviour
|
||||
{
|
||||
private const float DesignAspect = 1920f / 1080f;
|
||||
|
||||
private CanvasScaler scaler;
|
||||
private float lastAspect = -1f;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
scaler = GetComponent<CanvasScaler>();
|
||||
Apply();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// 分辨率/窗口变化时才重算。
|
||||
float aspect = (float)Screen.width / Mathf.Max(1, Screen.height);
|
||||
if (Mathf.Abs(aspect - lastAspect) > 0.0001f) Apply();
|
||||
}
|
||||
|
||||
private void Apply()
|
||||
{
|
||||
if (scaler == null) scaler = GetComponent<CanvasScaler>();
|
||||
if (scaler == null) return;
|
||||
if (scaler.uiScaleMode != CanvasScaler.ScaleMode.ScaleWithScreenSize) return;
|
||||
|
||||
float aspect = (float)Screen.width / Mathf.Max(1, Screen.height);
|
||||
lastAspect = aspect;
|
||||
|
||||
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
|
||||
// 更宽→锁高度(1);更窄→锁宽度(0)。等于始终匹配“更受限的一侧”,设计区域完整可见。
|
||||
scaler.matchWidthOrHeight = aspect >= DesignAspect ? 1f : 0f;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user