DesignResolutionConverter.cs 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using UnityEngine;
  2. namespace AppUI
  3. {
  4. /// <summary>
  5. /// 将「设计稿坐标系」下的像素尺寸/位置换算为 Unity UI CanvasScaler 的 referenceResolution 空间下的数值(与 Inspector 中 RectTransform 一致)。
  6. /// </summary>
  7. public static class DesignResolutionConverter
  8. {
  9. public const float DefaultDesignWidth = 402f;
  10. public const float DefaultDesignHeight = 874f;
  11. /// <summary>
  12. /// 各轴缩放:canvasRef / designArtboard。
  13. /// </summary>
  14. public static Vector2 GetScaleFactors(Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
  15. {
  16. if (designArtboardPx.x <= 0f || designArtboardPx.y <= 0f)
  17. {
  18. Debug.LogWarning("[DesignResolutionConverter] 设计稿宽高必须大于 0。");
  19. return Vector2.one;
  20. }
  21. return new Vector2(
  22. canvasReferenceResolution.x / designArtboardPx.x,
  23. canvasReferenceResolution.y / designArtboardPx.y);
  24. }
  25. /// <summary>
  26. /// 设计稿中的宽、高(像素)→ Canvas 参考分辨率空间下的 SizeDelta / 尺寸。
  27. /// </summary>
  28. public static Vector2 DesignSizeToCanvasUnits(Vector2 designSizePx, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
  29. {
  30. Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
  31. return new Vector2(designSizePx.x * s.x, designSizePx.y * s.y);
  32. }
  33. /// <summary>
  34. /// 单轴长度:设计稿 px → Canvas 参考分辨率空间(按宽度用 scaleX,按高度用 scaleY)。
  35. /// </summary>
  36. public static float DesignLengthToCanvas(float designPx, bool useWidthAxis, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
  37. {
  38. Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
  39. return designPx * (useWidthAxis ? s.x : s.y);
  40. }
  41. /// <summary>
  42. /// 单轴长度:Canvas 参考分辨率空间 → 设计稿 px。
  43. /// </summary>
  44. public static float CanvasLengthToDesign(float canvasUnits, bool useWidthAxis, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
  45. {
  46. Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
  47. float factor = useWidthAxis ? s.x : s.y;
  48. if (factor == 0f)
  49. return canvasUnits;
  50. return canvasUnits / factor;
  51. }
  52. /// <summary>
  53. /// Canvas 参考分辨率空间 → 设计稿像素(逆换算)。
  54. /// </summary>
  55. public static Vector2 CanvasUnitsToDesignSize(Vector2 canvasUnits, Vector2 designArtboardPx, Vector2 canvasReferenceResolution)
  56. {
  57. Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
  58. if (s.x == 0f || s.y == 0f)
  59. return canvasUnits;
  60. return new Vector2(canvasUnits.x / s.x, canvasUnits.y / s.y);
  61. }
  62. /// <summary>
  63. /// 设计稿中的点 (px),原点在左上角、X 向右、Y 向下(与常见 UI 设计工具一致)→
  64. /// Unity UI 以左下角为原点、Y 向上时,在参考分辨率空间中的 anchored 局部坐标(需结合锚点理解)。
  65. /// </summary>
  66. /// <param name="designPointTopLeftOriginPx">设计坐标,左上角为 (0,0),Y 向下增长。</param>
  67. public static Vector2 DesignPointToCanvasSpaceBottomLeftOrigin(
  68. Vector2 designPointTopLeftOriginPx,
  69. Vector2 designArtboardPx,
  70. Vector2 canvasReferenceResolution)
  71. {
  72. Vector2 s = GetScaleFactors(designArtboardPx, canvasReferenceResolution);
  73. float x = designPointTopLeftOriginPx.x * s.x;
  74. float yCanvas = (designArtboardPx.y - designPointTopLeftOriginPx.y) * s.y;
  75. return new Vector2(x, yCanvas);
  76. }
  77. }
  78. }