UIAdaptiveRect.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using UnityEngine;
  2. #if UNITY_EDITOR
  3. using UnityEditor;
  4. #endif
  5. namespace AdaptUI
  6. {
  7. [System.Serializable]
  8. public struct RectTransformData
  9. {
  10. public Vector2 anchorMin;
  11. public Vector2 anchorMax;
  12. public Vector2 anchoredPosition;
  13. public Vector2 sizeDelta;
  14. public RectTransformData(RectTransform rect)
  15. {
  16. anchorMin = rect.anchorMin;
  17. anchorMax = rect.anchorMax;
  18. anchoredPosition = rect.anchoredPosition;
  19. sizeDelta = rect.sizeDelta;
  20. }
  21. public bool IsValid()
  22. {
  23. return anchorMin != Vector2.zero || anchorMax != Vector2.zero || anchoredPosition != Vector2.zero || sizeDelta != Vector2.zero;
  24. }
  25. }
  26. [ExecuteAlways]
  27. [RequireComponent(typeof(RectTransform))]
  28. public class UIAdaptiveRect : MonoBehaviour
  29. {
  30. [Header("初始 布局")]
  31. [SerializeField] public RectTransformData defaultLayout;
  32. [Header("iPhone 布局")]
  33. [SerializeField] public RectTransformData iPhoneLayout;
  34. [Header("iPad 布局")]
  35. [SerializeField] public RectTransformData iPadLayout;
  36. private RectTransform rectTransform;
  37. //添加 isInitialized 变量,默认未初始化
  38. private bool isInitialized = false;
  39. private void Awake()
  40. {
  41. rectTransform = GetComponent<RectTransform>();
  42. #if UNITY_EDITOR
  43. // 如果未初始化,不要应用布局,等待 Reset() 赋值
  44. if (!isInitialized)
  45. {
  46. //Debug.Log("UIAdaptiveRect: 未初始化,跳过 ApplyLayout()");
  47. if (Application.isPlaying)
  48. ApplyLayout();
  49. return;
  50. }
  51. #endif
  52. ApplyLayout(); // 运行时应用 UI 适配
  53. }
  54. #if UNITY_EDITOR
  55. private void Reset()
  56. {
  57. rectTransform = GetComponent<RectTransform>();
  58. if (!isInitialized)
  59. {
  60. //Debug.Log("UIAdaptiveRect: 首次挂载,自动记录当前 UI 作为默认布局");
  61. defaultLayout = new RectTransformData(rectTransform);
  62. iPhoneLayout = new RectTransformData(rectTransform);
  63. iPadLayout = new RectTransformData(rectTransform);
  64. isInitialized = true; // ✅ 记录已初始化,避免 Awake() 误触
  65. }
  66. }
  67. // private void OnValidate()
  68. // {
  69. // if (rectTransform == null)
  70. // rectTransform = GetComponent<RectTransform>();
  71. // if (!iPhoneLayout.IsValid() || !iPadLayout.IsValid())
  72. // {
  73. // Debug.Log("📌 OnValidate: 重新初始化 iPhone & iPad 布局");
  74. // iPhoneLayout = new RectTransformData(rectTransform);
  75. // iPadLayout = new RectTransformData(rectTransform);
  76. // }
  77. // }
  78. #endif
  79. public void ApplyLayout()
  80. {
  81. if (rectTransform == null) return;
  82. DeviceTypeHelper.DeviceType deviceType = DeviceTypeHelper.DetectDeviceType();
  83. RectTransformData targetLayout = (deviceType == DeviceTypeHelper.DeviceType.iPhone) ? iPhoneLayout : iPadLayout;
  84. rectTransform.anchorMin = targetLayout.anchorMin;
  85. rectTransform.anchorMax = targetLayout.anchorMax;
  86. rectTransform.anchoredPosition = targetLayout.anchoredPosition;
  87. rectTransform.sizeDelta = targetLayout.sizeDelta;
  88. // Debug.Log($"📌 UI 适配完成: 设备 = {deviceType}, 位置 = {targetLayout.anchoredPosition}");
  89. }
  90. public RectTransformData GetLayout(bool isIpad)
  91. {
  92. return isIpad ? iPadLayout : iPhoneLayout;
  93. }
  94. public void SetLayout(bool isIpad, RectTransform rect)
  95. {
  96. if (isIpad)
  97. {
  98. iPadLayout = new RectTransformData(rect);
  99. }
  100. else
  101. {
  102. iPhoneLayout = new RectTransformData(rect);
  103. }
  104. // Debug.Log($"📌 UIAdaptiveRect: 设置布局为 {(isIpad ? "iPad" : "iPhone")}");
  105. }
  106. }
  107. }