BetterOffsetter.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using UnityEngine;
  6. using UnityEngine.EventSystems;
  7. using UnityEngine.Serialization;
  8. using UnityEngine.UI;
  9. namespace TheraBytes.BetterUi
  10. {
  11. #if UNITY_2018_3_OR_NEWER
  12. [ExecuteAlways]
  13. #else
  14. [ExecuteInEditMode]
  15. #endif
  16. [HelpURL("https://documentation.therabytes.de/better-ui/BetterOffsetter.html")]
  17. [RequireComponent(typeof(RectTransform))]
  18. [AddComponentMenu("Better UI/Layout/Better Offsetter", 30)]
  19. public class BetterOffsetter : UIBehaviour, ILayoutController, ILayoutSelfController, IResolutionDependency
  20. {
  21. [Serializable]
  22. public class Settings : IScreenConfigConnection
  23. {
  24. public bool ApplyPosX { get { return applyPosX; } set { applySizeX = value; } }
  25. public bool ApplyPosY { get { return applyPosY; } set { applyPosY = value; } }
  26. public bool ApplySizeX{ get { return applySizeX; } set { applySizeX = value; } }
  27. public bool ApplySizeY { get { return applySizeY; } set { applySizeY = value; } }
  28. [SerializeField]
  29. bool applyPosX = false;
  30. [SerializeField]
  31. bool applyPosY = false;
  32. [SerializeField]
  33. bool applySizeX = false;
  34. [SerializeField]
  35. bool applySizeY = false;
  36. [SerializeField]
  37. string screenConfigName;
  38. public string ScreenConfigName { get { return screenConfigName; } set { screenConfigName = value; } }
  39. }
  40. [Serializable]
  41. public class SettingsConfigCollection : SizeConfigCollection<Settings> { }
  42. public Settings CurrentSettings { get { return customSettings.GetCurrentItem(settingsFallback); } }
  43. [SerializeField]
  44. Settings settingsFallback = new Settings();
  45. [SerializeField]
  46. SettingsConfigCollection customSettings = new SettingsConfigCollection();
  47. public FloatSizeModifier AnchoredPositionXSizer
  48. {
  49. get { return customAnchorPosXSizers.GetCurrentItem(anchorPosXSizerFallback); }
  50. }
  51. public FloatSizeModifier AnchoredPositionYSizer
  52. {
  53. get { return customAnchorPosYSizers.GetCurrentItem(anchorPosYSizerFallback); }
  54. }
  55. public FloatSizeModifier SizeDeltaXSizer
  56. {
  57. get { return customSizeDeltaXSizers.GetCurrentItem(sizeDeltaXSizerFallback); }
  58. }
  59. public FloatSizeModifier SizeDeltaYSizer
  60. {
  61. get { return customSizeDeltaYSizers.GetCurrentItem(sizeDeltaYSizerFallback); }
  62. }
  63. [SerializeField] FloatSizeModifier anchorPosXSizerFallback = new FloatSizeModifier(100, 0, 1000);
  64. [SerializeField] FloatSizeConfigCollection customAnchorPosXSizers = new FloatSizeConfigCollection();
  65. [SerializeField] FloatSizeModifier anchorPosYSizerFallback = new FloatSizeModifier(100, 0, 1000);
  66. [SerializeField] FloatSizeConfigCollection customAnchorPosYSizers = new FloatSizeConfigCollection();
  67. [SerializeField] FloatSizeModifier sizeDeltaXSizerFallback = new FloatSizeModifier(100, 0, 1000);
  68. [SerializeField] FloatSizeConfigCollection customSizeDeltaXSizers = new FloatSizeConfigCollection();
  69. [SerializeField] FloatSizeModifier sizeDeltaYSizerFallback = new FloatSizeModifier(100, 0, 1000);
  70. [SerializeField] FloatSizeConfigCollection customSizeDeltaYSizers = new FloatSizeConfigCollection();
  71. DrivenRectTransformTracker rectTransformTracker = new DrivenRectTransformTracker();
  72. protected override void OnEnable()
  73. {
  74. base.OnEnable();
  75. ApplySize();
  76. }
  77. protected override void OnDisable()
  78. {
  79. base.OnDisable();
  80. rectTransformTracker.Clear();
  81. }
  82. #if UNITY_EDITOR
  83. protected override void OnValidate()
  84. {
  85. base.OnValidate();
  86. // NOTE: Unity sends a message when setting RectTransform.sizeDelta which is required here.
  87. // This logs a warning: "SendMessage cannot be called during Awake, CheckConsistency, or OnValidate"
  88. // However, everything seems to work anyway. Seems like there is no easy way to work around this problem.
  89. ApplySize();
  90. }
  91. #endif
  92. void ApplySize()
  93. {
  94. if (!isActiveAndEnabled)
  95. return;
  96. RectTransform rt = (this.transform as RectTransform);
  97. Vector2 pos = rt.anchoredPosition;
  98. Vector2 size = rt.sizeDelta;
  99. Settings settings = CurrentSettings;
  100. rectTransformTracker.Clear();
  101. if (settings.ApplySizeX)
  102. {
  103. size.x = SizeDeltaXSizer.CalculateSize(this);
  104. rectTransformTracker.Add(this, this.transform as RectTransform, DrivenTransformProperties.SizeDeltaX);
  105. }
  106. if (settings.ApplySizeY)
  107. {
  108. size.y = SizeDeltaYSizer.CalculateSize(this);
  109. rectTransformTracker.Add(this, this.transform as RectTransform, DrivenTransformProperties.SizeDeltaY);
  110. }
  111. if (settings.ApplyPosX)
  112. {
  113. pos.x = AnchoredPositionXSizer.CalculateSize(this);
  114. rectTransformTracker.Add(this, this.transform as RectTransform, DrivenTransformProperties.AnchoredPositionX);
  115. }
  116. if (settings.ApplyPosY)
  117. {
  118. pos.y = AnchoredPositionYSizer.CalculateSize(this);
  119. rectTransformTracker.Add(this, this.transform as RectTransform, DrivenTransformProperties.AnchoredPositionY);
  120. }
  121. rt.anchoredPosition = pos;
  122. rt.sizeDelta = size;
  123. }
  124. public void OnResolutionChanged()
  125. {
  126. ApplySize();
  127. }
  128. public void SetLayoutHorizontal()
  129. {
  130. ApplySize();
  131. }
  132. public void SetLayoutVertical()
  133. {
  134. ApplySize();
  135. }
  136. protected override void OnRectTransformDimensionsChange()
  137. {
  138. base.OnRectTransformDimensionsChange();
  139. ApplySize();
  140. }
  141. }
  142. }