using UnityEngine;
namespace AppUI
{
///
/// 将「设计稿坐标系」下的像素尺寸/位置换算为 Unity UI CanvasScaler 的 referenceResolution 空间下的数值(与 Inspector 中 RectTransform 一致)。
///
public static class DesignResolutionConverter
{
public const float DefaultDesignWidth = 402f;
public const float DefaultDesignHeight = 874f;
///
/// 各轴缩放:canvasRef / designArtboard。
///
public static Vector2 GetScaleFactors(Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
{
if (designArtboardPx.x <= 0f || designArtboardPx.y <= 0f)
{
Debug.LogWarning("[DesignResolutionConverter] 设计稿宽高必须大于 0。");
return Vector2.one;
}
return new Vector2(
canvasReferenceResolution.x / designArtboardPx.x,
canvasReferenceResolution.y / designArtboardPx.y);
}
///
/// 设计稿中的宽、高(像素)→ Canvas 参考分辨率空间下的 SizeDelta / 尺寸。
///
public static Vector2 DesignSizeToCanvasUnits(Vector2 designSizePx, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
{
Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
return new Vector2(designSizePx.x * s.x, designSizePx.y * s.y);
}
///
/// 单轴长度:设计稿 px → Canvas 参考分辨率空间(按宽度用 scaleX,按高度用 scaleY)。
///
public static float DesignLengthToCanvas(float designPx, bool useWidthAxis, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
{
Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
return designPx * (useWidthAxis ? s.x : s.y);
}
///
/// 单轴长度:Canvas 参考分辨率空间 → 设计稿 px。
///
public static float CanvasLengthToDesign(float canvasUnits, bool useWidthAxis, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
{
Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
float factor = useWidthAxis ? s.x : s.y;
if (factor == 0f)
return canvasUnits;
return canvasUnits / factor;
}
///
/// Canvas 参考分辨率空间 → 设计稿像素(逆换算)。
///
public static Vector2 CanvasUnitsToDesignSize(Vector2 canvasUnits, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
{
Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
if (s.x == 0f || s.y == 0f)
return canvasUnits;
return new Vector2(canvasUnits.x / s.x, canvasUnits.y / s.y);
}
///
/// 设计稿中的点 (px),原点在左上角、X 向右、Y 向下(与常见 UI 设计工具一致)→
/// Unity UI 以左下角为原点、Y 向上时,在参考分辨率空间中的 anchored 局部坐标(需结合锚点理解)。
///
/// 设计坐标,左上角为 (0,0),Y 向下增长。
public static Vector2 DesignPointToCanvasSpaceBottomLeftOrigin(
Vector2 designPointTopLeftOriginPx,
Vector2 designArtboardPx,
Vector2 canvasReferenceResolution)
{
Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
float x = designPointTopLeftOriginPx.x * s.x;
float yCanvas = (designArtboardPx.y - designPointTopLeftOriginPx.y) * s.y;
return new Vector2(x, yCanvas);
}
}
}