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); } } }