TextContainer.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. using UnityEngine;
  2. using UnityEngine.EventSystems;
  3. using System.Collections;
  4. namespace TMPro
  5. {
  6. public enum TextContainerAnchors { TopLeft = 0, Top = 1, TopRight = 2, Left = 3, Middle = 4, Right = 5, BottomLeft = 6, Bottom = 7, BottomRight = 8, Custom = 9 };
  7. [RequireComponent(typeof(RectTransform))]
  8. [AddComponentMenu("Layout/Text Container")]
  9. public class TextContainer : UIBehaviour
  10. {
  11. #pragma warning disable 0618 // Disabled warning related to deprecated properties. This is for backwards compatibility.
  12. public bool hasChanged
  13. {
  14. get { return m_hasChanged; }
  15. set { m_hasChanged = value; }
  16. }
  17. private bool m_hasChanged;
  18. // Pivot / Transform Position
  19. public Vector2 pivot
  20. {
  21. get { return m_pivot; }
  22. set { /*Debug.Log("Pivot has changed.");*/ if (m_pivot != value) { m_pivot = value; m_anchorPosition = GetAnchorPosition(m_pivot); m_hasChanged = true; OnContainerChanged(); } }
  23. }
  24. [SerializeField]
  25. private Vector2 m_pivot;
  26. public TextContainerAnchors anchorPosition
  27. {
  28. get { return m_anchorPosition; }
  29. set { /*Debug.Log("Anchor has changed.");*/ if (m_anchorPosition != value) { m_anchorPosition = value; m_pivot = GetPivot(m_anchorPosition); m_hasChanged = true; OnContainerChanged(); } }
  30. }
  31. [SerializeField]
  32. private TextContainerAnchors m_anchorPosition = TextContainerAnchors.Middle;
  33. // Rect which defines the Rectangle
  34. public Rect rect
  35. {
  36. get { return m_rect; }
  37. set { /*Debug.Log("Rectangle has changed.");*/ if (m_rect != value) { m_rect = value; /*m_size = new Vector2(m_rect.width, m_rect.height);*/ m_hasChanged = true; OnContainerChanged(); } }
  38. }
  39. [SerializeField]
  40. private Rect m_rect;
  41. public Vector2 size
  42. {
  43. get { return new Vector2(m_rect.width, m_rect.height); }
  44. set { /*Debug.Log("Size has changed.");*/ if (new Vector2(m_rect.width, m_rect.height) != value) { SetRect(value); m_hasChanged = true; m_isDefaultWidth = false; m_isDefaultHeight = false; OnContainerChanged(); } }
  45. }
  46. // Sets the width of the Text Container.
  47. public float width
  48. {
  49. get { return m_rect.width; }
  50. set { /*Debug.Log("Width has changed.");*/ SetRect(new Vector2(value, m_rect.height)); m_hasChanged = true; m_isDefaultWidth = false; OnContainerChanged(); }
  51. }
  52. // Sets the height of the Text Container.
  53. public float height
  54. {
  55. get { return m_rect.height; }
  56. set { SetRect(new Vector2(m_rect.width, value)); m_hasChanged = true; m_isDefaultHeight = false; OnContainerChanged(); }
  57. }
  58. // Used to determine if the user has changed the width of the Text Container.
  59. public bool isDefaultWidth
  60. {
  61. get { return m_isDefaultWidth; }
  62. }
  63. private bool m_isDefaultWidth;
  64. // Used to determine if the user has changed the height of the Text Container.
  65. public bool isDefaultHeight
  66. {
  67. get { return m_isDefaultHeight; }
  68. }
  69. private bool m_isDefaultHeight;
  70. public bool isAutoFitting
  71. {
  72. get { return m_isAutoFitting; }
  73. set { m_isAutoFitting = value; }
  74. }
  75. private bool m_isAutoFitting = false;
  76. // Corners of the Text Container
  77. public Vector3[] corners
  78. {
  79. get { return m_corners; }
  80. }
  81. private Vector3[] m_corners = new Vector3[4];
  82. public Vector3[] worldCorners
  83. {
  84. get { return m_worldCorners; }
  85. }
  86. private Vector3[] m_worldCorners = new Vector3[4];
  87. //public Vector3 normal
  88. //{
  89. // get { return m_normal; }
  90. //}
  91. //private Vector3 m_normal;
  92. // The margin offset from the Rectangle Bounds
  93. public Vector4 margins
  94. {
  95. get { return m_margins; }
  96. set { if (m_margins != value) { /*Debug.Log("Margins have changed.");*/ m_margins = value; m_hasChanged = true; OnContainerChanged(); } }
  97. }
  98. [SerializeField]
  99. private Vector4 m_margins;
  100. /// <summary>
  101. /// The RectTransform used by the object
  102. /// </summary>
  103. public RectTransform rectTransform
  104. {
  105. get
  106. {
  107. if (m_rectTransform == null) m_rectTransform = GetComponent<RectTransform>();
  108. return m_rectTransform;
  109. }
  110. }
  111. private RectTransform m_rectTransform;
  112. //private Transform m_transform;
  113. //private bool m_isAddingRectTransform;
  114. private static Vector2 k_defaultSize = new Vector2(100, 100);
  115. /// <summary>
  116. ///
  117. /// </summary>
  118. public TextMeshPro textMeshPro
  119. {
  120. get
  121. {
  122. if (m_textMeshPro == null) m_textMeshPro = GetComponent<TextMeshPro>();
  123. return m_textMeshPro;
  124. }
  125. }
  126. private TextMeshPro m_textMeshPro;
  127. protected override void Awake()
  128. {
  129. Debug.LogWarning("The Text Container component is now Obsolete and can safely be removed from [" + gameObject.name + "].", this);
  130. return;
  131. }
  132. /// <summary>
  133. ///
  134. /// </summary>
  135. protected override void OnEnable()
  136. {
  137. //Debug.Log("Text Container OnEnable() called.");
  138. OnContainerChanged();
  139. }
  140. /// <summary>
  141. ///
  142. /// </summary>
  143. protected override void OnDisable()
  144. {
  145. //Debug.Log("OnDisable() called.");
  146. }
  147. /// <summary>
  148. ///
  149. /// </summary>
  150. void OnContainerChanged()
  151. {
  152. //Debug.Log("OnContainerChanged");
  153. UpdateCorners();
  154. //UpdateWorldCorners();
  155. if (this.m_rectTransform != null)
  156. {
  157. m_rectTransform.sizeDelta = this.size;
  158. m_rectTransform.hasChanged = true;
  159. }
  160. if (this.textMeshPro != null)
  161. {
  162. m_textMeshPro.SetVerticesDirty();
  163. m_textMeshPro.margin = m_margins;
  164. }
  165. }
  166. #if UNITY_EDITOR
  167. /// <summary>
  168. ///
  169. /// </summary>
  170. protected override void OnValidate()
  171. {
  172. //Debug.Log("OnValidate() called.");
  173. m_hasChanged = true;
  174. OnContainerChanged();
  175. }
  176. #endif
  177. /*
  178. void LateUpdate()
  179. {
  180. // Used by the Run Time Text Input Component ... This will have to be changed.
  181. if (m_transform.hasChanged)
  182. UpdateWorldCorners();
  183. }
  184. */
  185. /// <summary>
  186. /// Callback from Unity to handle RectTransform changes.
  187. /// </summary>
  188. protected override void OnRectTransformDimensionsChange()
  189. {
  190. // Required to add a RectTransform to objects created in previous releases.
  191. if (this.rectTransform == null) m_rectTransform = gameObject.AddComponent<RectTransform>();
  192. if (m_rectTransform.sizeDelta != k_defaultSize)
  193. this.size = m_rectTransform.sizeDelta;
  194. pivot = m_rectTransform.pivot;
  195. m_hasChanged = true;
  196. OnContainerChanged();
  197. }
  198. private void SetRect(Vector2 size)
  199. {
  200. m_rect = new Rect(m_rect.x, m_rect.y, size.x, size.y);
  201. //UpdateCorners();
  202. }
  203. private void UpdateCorners()
  204. {
  205. m_corners[0] = new Vector3(-m_pivot.x * m_rect.width, (- m_pivot.y) * m_rect.height);
  206. m_corners[1] = new Vector3(-m_pivot.x * m_rect.width, (1 - m_pivot.y) * m_rect.height);
  207. m_corners[2] = new Vector3((1 - m_pivot.x) * m_rect.width, (1 - m_pivot.y) * m_rect.height);
  208. m_corners[3] = new Vector3((1 - m_pivot.x) * m_rect.width, (- m_pivot.y) * m_rect.height);
  209. //Debug.Log("Pivot " + m_pivot + " Corners 0: " + m_corners[0] + " 1: " + m_corners[1] + " 2: " + m_corners[2] + " 3: " + m_corners[3]);
  210. if (m_rectTransform != null)
  211. m_rectTransform.pivot = m_pivot;
  212. }
  213. //private void UpdateWorldCorners()
  214. //{
  215. // if (m_transform == null)
  216. // return;
  217. // Vector3 position = m_transform.position;
  218. // m_worldCorners[0] = position + m_transform.TransformDirection(m_corners[0]);
  219. // m_worldCorners[1] = position + m_transform.TransformDirection(m_corners[1]);
  220. // m_worldCorners[2] = position + m_transform.TransformDirection(m_corners[2]);
  221. // m_worldCorners[3] = position + m_transform.TransformDirection(m_corners[3]);
  222. // m_normal = Vector3.Cross(worldCorners[1] - worldCorners[0], worldCorners[3] - worldCorners[0]);
  223. //}
  224. //public Vector3[] GetWorldCorners()
  225. //{
  226. // UpdateWorldCorners();
  227. // return m_worldCorners;
  228. //}
  229. Vector2 GetPivot(TextContainerAnchors anchor)
  230. {
  231. Vector2 pivot = Vector2.zero;
  232. switch (anchor)
  233. {
  234. case TextContainerAnchors.TopLeft:
  235. pivot = new Vector2(0, 1);
  236. break;
  237. case TextContainerAnchors.Top:
  238. pivot = new Vector2(0.5f, 1);
  239. break;
  240. case TextContainerAnchors.TopRight:
  241. pivot = new Vector2(1, 1);
  242. break;
  243. case TextContainerAnchors.Left:
  244. pivot = new Vector2(0, 0.5f);
  245. break;
  246. case TextContainerAnchors.Middle:
  247. pivot = new Vector2(0.5f, 0.5f);
  248. break;
  249. case TextContainerAnchors.Right:
  250. pivot = new Vector2(1, 0.5f);
  251. break;
  252. case TextContainerAnchors.BottomLeft:
  253. pivot = new Vector2(0, 0);
  254. break;
  255. case TextContainerAnchors.Bottom:
  256. pivot = new Vector2(0.5f, 0);
  257. break;
  258. case TextContainerAnchors.BottomRight:
  259. pivot = new Vector2(1, 0);
  260. break;
  261. }
  262. return pivot;
  263. }
  264. // Method which returns the Anchor position based on pivot value.
  265. TextContainerAnchors GetAnchorPosition(Vector2 pivot)
  266. {
  267. if (pivot == new Vector2(0, 1))
  268. return TextContainerAnchors.TopLeft;
  269. else if (pivot == new Vector2(0.5f, 1))
  270. return TextContainerAnchors.Top;
  271. else if (pivot == new Vector2(1f, 1))
  272. return TextContainerAnchors.TopRight;
  273. else if (pivot == new Vector2(0, 0.5f))
  274. return TextContainerAnchors.Left;
  275. else if (pivot == new Vector2(0.5f, 0.5f))
  276. return TextContainerAnchors.Middle;
  277. else if (pivot == new Vector2(1, 0.5f))
  278. return TextContainerAnchors.Right;
  279. else if (pivot == new Vector2(0, 0))
  280. return TextContainerAnchors.BottomLeft;
  281. else if (pivot == new Vector2(0.5f, 0))
  282. return TextContainerAnchors.Bottom;
  283. else if (pivot == new Vector2(1, 0))
  284. return TextContainerAnchors.BottomRight;
  285. else
  286. return TextContainerAnchors.Custom;
  287. }
  288. }
  289. }