暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TextMeshPro.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. using UnityEngine;
  2. using System;
  3. using UnityEngine.UI;
  4. namespace TMPro
  5. {
  6. [DisallowMultipleComponent]
  7. [RequireComponent(typeof(MeshRenderer))]
  8. [AddComponentMenu("Mesh/TextMeshPro - Text")]
  9. [ExecuteAlways]
  10. [HelpURL("https://docs.unity3d.com/Packages/com.unity.textmeshpro@3.0")]
  11. public partial class TextMeshPro : TMP_Text, ILayoutElement
  12. {
  13. // Public Properties and Serializable Properties
  14. [SerializeField] internal int _SortingLayer;
  15. /// <summary>
  16. /// Sets the Renderer's sorting Layer ID
  17. /// </summary>
  18. public int sortingLayerID
  19. {
  20. get
  21. {
  22. if (renderer == null)
  23. return 0;
  24. return m_renderer.sortingLayerID;
  25. }
  26. set
  27. {
  28. if (renderer == null)
  29. return;
  30. m_renderer.sortingLayerID = value;
  31. _SortingLayerID = value;
  32. // Make sure sorting layer ID change is also reflected on sub text objects.
  33. UpdateSubMeshSortingLayerID(value);
  34. }
  35. }
  36. [SerializeField]
  37. internal int _SortingLayerID;
  38. /// <summary>
  39. /// Sets the Renderer's sorting order within the assigned layer.
  40. /// </summary>
  41. public int sortingOrder
  42. {
  43. get
  44. {
  45. if (renderer == null)
  46. return 0;
  47. return m_renderer.sortingOrder;
  48. }
  49. set
  50. {
  51. if (renderer == null)
  52. return;
  53. m_renderer.sortingOrder = value;
  54. _SortingOrder = value;
  55. // Make sure sorting order change is also reflected on sub text objects.
  56. UpdateSubMeshSortingOrder(value);
  57. }
  58. }
  59. [SerializeField]
  60. internal int _SortingOrder;
  61. /// <summary>
  62. /// Determines if the size of the text container will be adjusted to fit the text object when it is first created.
  63. /// </summary>
  64. public override bool autoSizeTextContainer
  65. {
  66. get { return m_autoSizeTextContainer; }
  67. set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { TMP_UpdateManager.RegisterTextElementForLayoutRebuild(this); SetLayoutDirty(); } }
  68. }
  69. /// <summary>
  70. /// Returns a reference to the Text Container
  71. /// </summary>
  72. [Obsolete("The TextContainer is now obsolete. Use the RectTransform instead.")]
  73. public TextContainer textContainer
  74. {
  75. get
  76. {
  77. return null;
  78. }
  79. }
  80. /// <summary>
  81. /// Returns a reference to the Transform
  82. /// </summary>
  83. public new Transform transform
  84. {
  85. get
  86. {
  87. if (m_transform == null)
  88. m_transform = GetComponent<Transform>();
  89. return m_transform;
  90. }
  91. }
  92. #pragma warning disable 0108
  93. /// <summary>
  94. /// Returns the rendered assigned to the text object.
  95. /// </summary>
  96. public Renderer renderer
  97. {
  98. get
  99. {
  100. if (m_renderer == null)
  101. m_renderer = GetComponent<Renderer>();
  102. return m_renderer;
  103. }
  104. }
  105. /// <summary>
  106. /// Returns the mesh assigned to the text object.
  107. /// </summary>
  108. public override Mesh mesh
  109. {
  110. get
  111. {
  112. if (m_mesh == null)
  113. {
  114. m_mesh = new Mesh();
  115. m_mesh.hideFlags = HideFlags.HideAndDontSave;
  116. }
  117. return m_mesh;
  118. }
  119. }
  120. /// <summary>
  121. /// Returns the Mesh Filter of the text object.
  122. /// </summary>
  123. public MeshFilter meshFilter
  124. {
  125. get
  126. {
  127. if (m_meshFilter == null)
  128. {
  129. m_meshFilter = GetComponent<MeshFilter>();
  130. if (m_meshFilter == null)
  131. {
  132. m_meshFilter = gameObject.AddComponent<MeshFilter>();
  133. m_meshFilter.hideFlags = HideFlags.HideInInspector | HideFlags.HideAndDontSave;
  134. }
  135. }
  136. return m_meshFilter;
  137. }
  138. }
  139. // MASKING RELATED PROPERTIES
  140. /// <summary>
  141. /// Sets the mask type
  142. /// </summary>
  143. public MaskingTypes maskType
  144. {
  145. get { return m_maskType; }
  146. set { m_maskType = value; SetMask(m_maskType); }
  147. }
  148. /// <summary>
  149. /// Function used to set the mask type and coordinates in World Space
  150. /// </summary>
  151. /// <param name="type"></param>
  152. /// <param name="maskCoords"></param>
  153. public void SetMask(MaskingTypes type, Vector4 maskCoords)
  154. {
  155. SetMask(type);
  156. SetMaskCoordinates(maskCoords);
  157. }
  158. /// <summary>
  159. /// Function used to set the mask type, coordinates and softness
  160. /// </summary>
  161. /// <param name="type"></param>
  162. /// <param name="maskCoords"></param>
  163. /// <param name="softnessX"></param>
  164. /// <param name="softnessY"></param>
  165. public void SetMask(MaskingTypes type, Vector4 maskCoords, float softnessX, float softnessY)
  166. {
  167. SetMask(type);
  168. SetMaskCoordinates(maskCoords, softnessX, softnessY);
  169. }
  170. /// <summary>
  171. /// Schedule rebuilding of the text geometry.
  172. /// </summary>
  173. public override void SetVerticesDirty()
  174. {
  175. //Debug.Log("***** SetVerticesDirty() called on object [" + this.name + "] at frame [" + Time.frameCount + "] *****");
  176. if (this == null || !this.IsActive())
  177. return;
  178. TMP_UpdateManager.RegisterTextElementForGraphicRebuild(this);
  179. }
  180. /// <summary>
  181. ///
  182. /// </summary>
  183. public override void SetLayoutDirty()
  184. {
  185. m_isPreferredWidthDirty = true;
  186. m_isPreferredHeightDirty = true;
  187. if (this == null || !this.IsActive())
  188. return;
  189. LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);
  190. m_isLayoutDirty = true;
  191. }
  192. /// <summary>
  193. /// Schedule updating of the material used by the text object.
  194. /// </summary>
  195. public override void SetMaterialDirty()
  196. {
  197. //Debug.Log("SetMaterialDirty()");
  198. //if (!this.IsActive())
  199. // return;
  200. //m_isMaterialDirty = true;
  201. UpdateMaterial();
  202. //TMP_UpdateManager.RegisterTextElementForGraphicRebuild(this);
  203. }
  204. /// <summary>
  205. ///
  206. /// </summary>
  207. public override void SetAllDirty()
  208. {
  209. SetLayoutDirty();
  210. SetVerticesDirty();
  211. SetMaterialDirty();
  212. }
  213. /// <summary>
  214. ///
  215. /// </summary>
  216. /// <param name="update"></param>
  217. public override void Rebuild(CanvasUpdate update)
  218. {
  219. if (this == null) return;
  220. if (update == CanvasUpdate.Prelayout)
  221. {
  222. if (m_autoSizeTextContainer)
  223. {
  224. m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);
  225. }
  226. }
  227. else if (update == CanvasUpdate.PreRender)
  228. {
  229. this.OnPreRenderObject();
  230. if (!m_isMaterialDirty) return;
  231. UpdateMaterial();
  232. m_isMaterialDirty = false;
  233. }
  234. }
  235. /// <summary>
  236. ///
  237. /// </summary>
  238. protected override void UpdateMaterial()
  239. {
  240. //Debug.Log("***** UpdateMaterial() called on object ID " + GetInstanceID() + ". *****");
  241. //if (!this.IsActive())
  242. // return;
  243. if (renderer == null || m_sharedMaterial == null)
  244. return;
  245. // Only update the material if it has changed.
  246. if (m_renderer.sharedMaterial == null || m_renderer.sharedMaterial.GetInstanceID() != m_sharedMaterial.GetInstanceID())
  247. m_renderer.sharedMaterial = m_sharedMaterial;
  248. }
  249. /// <summary>
  250. /// Function to be used to force recomputing of character padding when Shader / Material properties have been changed via script.
  251. /// </summary>
  252. public override void UpdateMeshPadding()
  253. {
  254. m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);
  255. m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
  256. m_havePropertiesChanged = true;
  257. checkPaddingRequired = false;
  258. // Return if text object is not awake yet.
  259. if (m_textInfo == null) return;
  260. // Update sub text objects
  261. for (int i = 1; i < m_textInfo.materialCount; i++)
  262. m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);
  263. }
  264. /// <summary>
  265. /// Function to force regeneration of the text object before its normal process time. This is useful when changes to the text object properties need to be applied immediately.
  266. /// </summary>
  267. /// <param name="ignoreActiveState">Ignore Active State of text objects. Inactive objects are ignored by default.</param>
  268. /// <param name="forceTextReparsing">Force re-parsing of the text.</param>
  269. public override void ForceMeshUpdate(bool ignoreActiveState = false, bool forceTextReparsing = false)
  270. {
  271. m_havePropertiesChanged = true;
  272. m_ignoreActiveState = ignoreActiveState;
  273. OnPreRenderObject();
  274. }
  275. /// <summary>
  276. /// Function used to evaluate the length of a text string.
  277. /// </summary>
  278. /// <param name="text"></param>
  279. /// <returns></returns>
  280. public override TMP_TextInfo GetTextInfo(string text)
  281. {
  282. SetText(text);
  283. SetArraySizes(m_TextProcessingArray);
  284. m_renderMode = TextRenderFlags.DontRender;
  285. ComputeMarginSize();
  286. GenerateTextMesh();
  287. m_renderMode = TextRenderFlags.Render;
  288. return this.textInfo;
  289. }
  290. /// <summary>
  291. /// Function to clear the geometry of the Primary and Sub Text objects.
  292. /// </summary>
  293. public override void ClearMesh(bool updateMesh)
  294. {
  295. if (m_textInfo.meshInfo[0].mesh == null) m_textInfo.meshInfo[0].mesh = m_mesh;
  296. m_textInfo.ClearMeshInfo(updateMesh);
  297. }
  298. /// <summary>
  299. /// Event to allow users to modify the content of the text info before the text is rendered.
  300. /// </summary>
  301. public override event Action<TMP_TextInfo> OnPreRenderText;
  302. /// <summary>
  303. /// Function to update the geometry of the main and sub text objects.
  304. /// </summary>
  305. /// <param name="mesh"></param>
  306. /// <param name="index"></param>
  307. public override void UpdateGeometry(Mesh mesh, int index)
  308. {
  309. mesh.RecalculateBounds();
  310. }
  311. /// <summary>
  312. /// Function to upload the updated vertex data and renderer.
  313. /// </summary>
  314. public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)
  315. {
  316. int materialCount = m_textInfo.materialCount;
  317. for (int i = 0; i < materialCount; i++)
  318. {
  319. Mesh mesh;
  320. if (i == 0)
  321. mesh = m_mesh;
  322. else
  323. {
  324. // Clear unused vertices
  325. // TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.
  326. //m_textInfo.meshInfo[i].ClearUnusedVertices();
  327. mesh = m_subTextObjects[i].mesh;
  328. }
  329. //mesh.MarkDynamic();
  330. if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)
  331. mesh.vertices = m_textInfo.meshInfo[i].vertices;
  332. if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)
  333. mesh.uv = m_textInfo.meshInfo[i].uvs0;
  334. if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)
  335. mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
  336. //if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)
  337. // mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
  338. if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)
  339. mesh.colors32 = m_textInfo.meshInfo[i].colors32;
  340. mesh.RecalculateBounds();
  341. }
  342. }
  343. /// <summary>
  344. /// Function to upload the updated vertex data and renderer.
  345. /// </summary>
  346. public override void UpdateVertexData()
  347. {
  348. int materialCount = m_textInfo.materialCount;
  349. for (int i = 0; i < materialCount; i++)
  350. {
  351. Mesh mesh;
  352. if (i == 0)
  353. mesh = m_mesh;
  354. else
  355. {
  356. // Clear unused vertices
  357. m_textInfo.meshInfo[i].ClearUnusedVertices();
  358. mesh = m_subTextObjects[i].mesh;
  359. }
  360. //mesh.MarkDynamic();
  361. mesh.vertices = m_textInfo.meshInfo[i].vertices;
  362. mesh.uv = m_textInfo.meshInfo[i].uvs0;
  363. mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
  364. //mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
  365. mesh.colors32 = m_textInfo.meshInfo[i].colors32;
  366. mesh.RecalculateBounds();
  367. }
  368. }
  369. public void UpdateFontAsset()
  370. {
  371. LoadFontAsset();
  372. }
  373. private bool m_currentAutoSizeMode;
  374. public void CalculateLayoutInputHorizontal() { }
  375. public void CalculateLayoutInputVertical() { }
  376. }
  377. }