Hue Preserving Color Blending
TextMeshProUGUI.cs
1 using UnityEngine;
2 using System;
3 using System.Collections;
4 using System.Collections.Generic;
5 
6 using UnityEngine.UI;
7 using UnityEngine.EventSystems;
8 using UnityEngine.UI.CoroutineTween;
9 
10 
11 #pragma warning disable 0414 // Disabled a few warnings related to serialized variables not used in this script but used in the editor.
12 
13 namespace TMPro
14 {
15 
16  [ExecuteInEditMode]
17  [DisallowMultipleComponent]
18  [RequireComponent(typeof(RectTransform))]
19  [RequireComponent(typeof(CanvasRenderer))]
20  [AddComponentMenu("UI/TextMeshPro - Text (UI)", 11)]
21  public partial class TextMeshProUGUI : TMP_Text, ILayoutElement
22  {
26  public override Material materialForRendering
27  {
28  get { return TMP_MaterialManager.GetMaterialForRendering(this, m_sharedMaterial); }
29  }
30 
34  public override bool autoSizeTextContainer
35  {
36  get { return m_autoSizeTextContainer; }
37 
38  set { if (m_autoSizeTextContainer == value) return; m_autoSizeTextContainer = value; if (m_autoSizeTextContainer) { CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); SetLayoutDirty(); } }
39  }
40 
41 
42 
46  public override Mesh mesh
47  {
48  get { return m_mesh; }
49  }
50 
51 
55  public new CanvasRenderer canvasRenderer
56  {
57  get
58  {
59  if (m_canvasRenderer == null) m_canvasRenderer = GetComponent<CanvasRenderer>();
60 
61  return m_canvasRenderer;
62  }
63  }
64 
65 
69  //public bool anchorDampening
70  //{
71  // get { return m_anchorDampening; }
72  // set { if (m_anchorDampening != value) { havePropertiesChanged = true; m_anchorDampening = value; /* ScheduleUpdate(); */ } }
73  //}
74 
75 
76  private bool m_isRebuildingLayout = false;
77  //private bool m_isLayoutDirty = false;
78 
79 
84  {
85  //Debug.Log("*** CalculateLayoutHorizontal() ***"); // at Frame: " + Time.frameCount); // called on Object ID " + GetInstanceID());
86 
88  if (!this.gameObject.activeInHierarchy)
89  return;
90 
91  if (m_isCalculateSizeRequired || m_rectTransform.hasChanged)
92  {
93  m_preferredWidth = GetPreferredWidth();
94 
96 
97  m_isLayoutDirty = true;
98  }
99  }
100 
101 
106  {
107  //Debug.Log("*** CalculateLayoutInputVertical() ***"); // at Frame: " + Time.frameCount); // called on Object ID " + GetInstanceID());
108 
110  if (!this.gameObject.activeInHierarchy) // || IsRectTransformDriven == false)
111  return;
112 
113  if (m_isCalculateSizeRequired || m_rectTransform.hasChanged)
114  {
115  m_preferredHeight = GetPreferredHeight();
116 
118 
119  m_isLayoutDirty = true;
120  }
121 
122  m_isCalculateSizeRequired = false;
123  }
124 
125 
126  public override void SetVerticesDirty()
127  {
128  if (m_verticesAlreadyDirty || this == null || !this.IsActive() || CanvasUpdateRegistry.IsRebuildingGraphics())
129  return;
130 
131  m_verticesAlreadyDirty = true;
132  CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild((ICanvasElement)this);
133 
134  if (m_OnDirtyVertsCallback != null)
135  m_OnDirtyVertsCallback();
136  }
137 
138 
142  public override void SetLayoutDirty()
143  {
144  m_isPreferredWidthDirty = true;
145  m_isPreferredHeightDirty = true;
146 
147  if ( m_layoutAlreadyDirty || this == null || !this.IsActive())
148  return;
149 
150  m_layoutAlreadyDirty = true;
151  LayoutRebuilder.MarkLayoutForRebuild(this.rectTransform);
152 
153  m_isLayoutDirty = true;
154 
155  if (m_OnDirtyLayoutCallback != null)
156  m_OnDirtyLayoutCallback();
157  }
158 
159 
163  public override void SetMaterialDirty()
164  {
165  //Debug.Log("SetMaterialDirty()");
166 
167  if (this == null || !this.IsActive() || CanvasUpdateRegistry.IsRebuildingGraphics())
168  return;
169 
170  m_isMaterialDirty = true;
171  CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild((ICanvasElement)this);
172 
173  if (m_OnDirtyMaterialCallback != null)
174  m_OnDirtyMaterialCallback();
175  }
176 
177 
181  public override void SetAllDirty()
182  {
183  m_isInputParsingRequired = true;
184 
185  SetLayoutDirty();
186  SetVerticesDirty();
188  }
189 
190 
191 
196  public override void Rebuild(CanvasUpdate update)
197  {
198  if (this == null) return;
199 
200  if (update == CanvasUpdate.Prelayout)
201  {
202  if (m_autoSizeTextContainer)
203  {
204  m_rectTransform.sizeDelta = GetPreferredValues(Mathf.Infinity, Mathf.Infinity);
205  }
206  }
207  else if (update == CanvasUpdate.PreRender)
208  {
209  OnPreRenderCanvas();
210 
211  m_verticesAlreadyDirty = false;
212  m_layoutAlreadyDirty = false;
213 
214  if (!m_isMaterialDirty) return;
215 
216  UpdateMaterial();
217  m_isMaterialDirty = false;
218  }
219  }
220 
221 
225  private void UpdateSubObjectPivot()
226  {
227  if (m_textInfo == null) return;
228 
229  for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)
230  {
231  m_subTextObjects[i].SetPivotDirty();
232  }
233  //m_isPivotDirty = false;
234  }
235 
236 
242  public override Material GetModifiedMaterial(Material baseMaterial)
243  {
244  Material mat = baseMaterial;
245 
246  if (m_ShouldRecalculateStencil)
247  {
248  m_stencilID = TMP_MaterialManager.GetStencilID(gameObject);
249  m_ShouldRecalculateStencil = false;
250  }
251 
252  // Release masking material
253  //if (m_MaskMaterial != null)
254  // MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
255 
256  if (m_stencilID > 0)
257  {
258  mat = TMP_MaterialManager.GetStencilMaterial(baseMaterial, m_stencilID);
259  if (m_MaskMaterial != null)
260  TMP_MaterialManager.ReleaseStencilMaterial(m_MaskMaterial);
261 
262  m_MaskMaterial = mat;
263  }
264 
265  return mat;
266  }
267 
268 
272  protected override void UpdateMaterial()
273  {
274  //Debug.Log("*** UpdateMaterial() ***");
275 
276  //if (!this.IsActive())
277  // return;
278 
279  if (m_sharedMaterial == null) return;
280 
281  if (m_canvasRenderer == null) m_canvasRenderer = this.canvasRenderer;
282 
283  m_canvasRenderer.materialCount = 1;
284  m_canvasRenderer.SetMaterial(materialForRendering, 0);
285  }
286 
287 
288  //public override void OnRebuildRequested()
289  //{
290  // //Debug.Log("OnRebuildRequested");
291 
292  // base.OnRebuildRequested();
293  //}
294 
295 
296 
297  //public override bool Raycast(Vector2 sp, Camera eventCamera)
298  //{
299  // //Debug.Log("Raycast Event. ScreenPoint: " + sp);
300  // return base.Raycast(sp, eventCamera);
301  //}
302 
303 
304  // MASKING RELATED PROPERTIES
308  public Vector4 maskOffset
309  {
310  get { return m_maskOffset; }
311  set { m_maskOffset = value; UpdateMask(); m_havePropertiesChanged = true; }
312  }
313 
314 
315  //public override Material defaultMaterial
316  //{
317  // get { Debug.Log("Default Material called."); return m_sharedMaterial; }
318  //}
319 
320 
321 
322  //protected override void OnCanvasHierarchyChanged()
323  //{
324  // //Debug.Log("OnCanvasHierarchyChanged...");
325  //}
326 
327 
328  // IClippable implementation
332  public override void RecalculateClipping()
333  {
334  //Debug.Log("***** RecalculateClipping() *****");
335 
336  base.RecalculateClipping();
337  }
338 
339  // IMaskable Implementation
343  public override void RecalculateMasking()
344  {
345  //Debug.Log("***** RecalculateMasking() *****");
346 
347  this.m_ShouldRecalculateStencil = true;
349  }
350 
356  public override void Cull(Rect clipRect, bool validRect)
357  {
358  if (m_ignoreRectMaskCulling) return;
359 
360  base.Cull(clipRect, validRect);
361  }
362 
363 
364  //protected override void UpdateGeometry()
365  //{
366  // //Debug.Log("UpdateGeometry");
367  // //base.UpdateGeometry();
368  //}
369 
370 
371  //protected override void UpdateMaterial()
372  //{
373  // //Debug.Log("UpdateMaterial called.");
375  //}
376 
377 
378  /*
382  public MaskingTypes mask
383  {
384  get { return m_mask; }
385  set { m_mask = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
386  }
387 
391  public MaskingOffsetMode maskOffsetMode
392  {
393  get { return m_maskOffsetMode; }
394  set { m_maskOffsetMode = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
395  }
396  */
397 
398 
399 
400  /*
404  public Vector2 maskSoftness
405  {
406  get { return m_maskSoftness; }
407  set { m_maskSoftness = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
408  }
409 
413  public Vector2 vertexOffset
414  {
415  get { return m_vertexOffset; }
416  set { m_vertexOffset = value; havePropertiesChanged = true; isMaskUpdateRequired = true; }
417  }
418  */
419 
420 
424  public override void UpdateMeshPadding()
425  {
426  m_padding = ShaderUtilities.GetPadding(m_sharedMaterial, m_enableExtraPadding, m_isUsingBold);
427  m_isMaskingEnabled = ShaderUtilities.IsMaskingEnabled(m_sharedMaterial);
428  m_havePropertiesChanged = true;
429  checkPaddingRequired = false;
430 
431  // Return if text object is not awake yet.
432  if (m_textInfo == null) return;
433 
434  // Update sub text objects
435  for (int i = 1; i < m_textInfo.materialCount; i++)
436  m_subTextObjects[i].UpdateMeshPadding(m_enableExtraPadding, m_isUsingBold);
437  }
438 
439 
447  protected override void InternalCrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha)
448  {
449  int materialCount = m_textInfo.materialCount;
450 
451  for (int i = 1; i < materialCount; i++)
452  {
453  m_subTextObjects[i].CrossFadeColor(targetColor, duration, ignoreTimeScale, useAlpha);
454  }
455  }
456 
457 
464  protected override void InternalCrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale)
465  {
466  int materialCount = m_textInfo.materialCount;
467 
468  for (int i = 1; i < materialCount; i++)
469  {
470  m_subTextObjects[i].CrossFadeAlpha(alpha, duration, ignoreTimeScale);
471  }
472  }
473 
474 
478  public override void ForceMeshUpdate()
479  {
480  //if (m_isEnabled == false) this.OnEnable();
481 
482  m_havePropertiesChanged = true;
483  OnPreRenderCanvas();
484  }
485 
486 
491  public override void ForceMeshUpdate(bool ignoreInactive)
492  {
493  m_havePropertiesChanged = true;
494  m_ignoreActiveState = true;
495  OnPreRenderCanvas();
496  }
497 
498 
504  public override TMP_TextInfo GetTextInfo(string text)
505  {
506  StringToCharArray(text, ref m_char_buffer);
507  SetArraySizes(m_char_buffer);
508 
509  m_renderMode = TextRenderFlags.DontRender;
510 
512 
513  // Need to make sure we have a valid reference to a Canvas.
514  if (m_canvas == null) m_canvas = this.canvas;
515 
517 
518  m_renderMode = TextRenderFlags.Render;
519 
520  return this.textInfo;
521  }
522 
526  public override void ClearMesh()
527  {
528  m_canvasRenderer.SetMesh(null);
529 
530  for (int i = 1; i < m_subTextObjects.Length && m_subTextObjects[i] != null; i++)
531  m_subTextObjects[i].canvasRenderer.SetMesh(null);
532 
533  //if (m_linkedTextComponent != null)
534  // m_linkedTextComponent.ClearMesh();
535  }
536 
537 
542  //public override void ForceMeshUpdate(TMP_VertexDataUpdateFlags flags) { }
543 
544 
550  public override void UpdateGeometry(Mesh mesh, int index)
551  {
552  mesh.RecalculateBounds();
553 
554  if (index == 0)
555  {
556  m_canvasRenderer.SetMesh(mesh);
557  }
558  else
559  {
560  m_subTextObjects[index].canvasRenderer.SetMesh(mesh);
561  }
562  }
563 
564 
568  public override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)
569  {
570  int materialCount = m_textInfo.materialCount;
571 
572  for (int i = 0; i < materialCount; i++)
573  {
574  Mesh mesh;
575 
576  if (i == 0)
577  mesh = m_mesh;
578  else
579  {
580  // Clear unused vertices
581  // TODO: Causes issues when sorting geometry as last vertex data attribute get wiped out.
582  //m_textInfo.meshInfo[i].ClearUnusedVertices();
583 
584  mesh = m_subTextObjects[i].mesh;
585  }
586 
587  if ((flags & TMP_VertexDataUpdateFlags.Vertices) == TMP_VertexDataUpdateFlags.Vertices)
588  mesh.vertices = m_textInfo.meshInfo[i].vertices;
589 
590  if ((flags & TMP_VertexDataUpdateFlags.Uv0) == TMP_VertexDataUpdateFlags.Uv0)
591  mesh.uv = m_textInfo.meshInfo[i].uvs0;
592 
593  if ((flags & TMP_VertexDataUpdateFlags.Uv2) == TMP_VertexDataUpdateFlags.Uv2)
594  mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
595 
596  //if ((flags & TMP_VertexDataUpdateFlags.Uv4) == TMP_VertexDataUpdateFlags.Uv4)
597  // mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
598 
599  if ((flags & TMP_VertexDataUpdateFlags.Colors32) == TMP_VertexDataUpdateFlags.Colors32)
600  mesh.colors32 = m_textInfo.meshInfo[i].colors32;
601 
602  mesh.RecalculateBounds();
603 
604  if (i == 0)
605  m_canvasRenderer.SetMesh(mesh);
606  else
607  m_subTextObjects[i].canvasRenderer.SetMesh(mesh);
608  }
609  }
610 
611 
615  public override void UpdateVertexData()
616  {
617  int materialCount = m_textInfo.materialCount;
618 
619  for (int i = 0; i < materialCount; i++)
620  {
621  Mesh mesh;
622 
623  if (i == 0)
624  mesh = m_mesh;
625  else
626  {
627  // Clear unused vertices
628  m_textInfo.meshInfo[i].ClearUnusedVertices();
629 
630  mesh = m_subTextObjects[i].mesh;
631  }
632 
633  //mesh.MarkDynamic();
634  mesh.vertices = m_textInfo.meshInfo[i].vertices;
635  mesh.uv = m_textInfo.meshInfo[i].uvs0;
636  mesh.uv2 = m_textInfo.meshInfo[i].uvs2;
637  //mesh.uv4 = m_textInfo.meshInfo[i].uvs4;
638  mesh.colors32 = m_textInfo.meshInfo[i].colors32;
639 
640  mesh.RecalculateBounds();
641 
642  if (i == 0)
643  m_canvasRenderer.SetMesh(mesh);
644  else
645  m_subTextObjects[i].canvasRenderer.SetMesh(mesh);
646  }
647  }
648 
649 
650  public void UpdateFontAsset()
651  {
652  LoadFontAsset();
653  }
654 
655  }
656 }
Vector2 GetPreferredValues()
Function to Calculate the Preferred Width and Height of the text object.
Definition: TMP_Text.cs:3411
override void GenerateTextMesh()
This is the main function that is responsible for creating / displaying the text.
TextRenderFlags
Flags controlling what vertex data gets pushed to the mesh.
Definition: TMP_Text.cs:88
override void Cull(Rect clipRect, bool validRect)
Override of the Cull function to provide for the ability to override the culling of the text object.
void ClearUnusedVertices()
Function to clear the vertices while preserving the Triangles, Normals and Tangents.
float alpha
Sets the vertex color alpha value.
Definition: TMP_Text.cs:247
override void ForceMeshUpdate()
Function to force regeneration of the mesh before its normal process time. This is useful when change...
Vector4 maskOffset
Sets the masking offset from the bounds of the object
override void SetLayoutDirty()
new CanvasRenderer canvasRenderer
Reference to the CanvasRenderer used by the text object.
Class which contains information about every element contained within the text object.
Definition: TMP_TextInfo.cs:13
override void Rebuild(CanvasUpdate update)
override void UpdateVertexData(TMP_VertexDataUpdateFlags flags)
Function to upload the updated vertex data and renderer.
override void SetMaterialDirty()
override Material materialForRendering
Get the material that will be used for rendering.
void CalculateLayoutInputVertical()
Function called by Unity when the vertical layout needs to be recalculated.
override bool autoSizeTextContainer
Determines if the size of the text container will be adjusted to fit the text object when it is first...
void StringToCharArray(string sourceText, ref int[] charBuffer)
Method to store the content of a string into an integer array.
Definition: TMP_Text.cs:2286
override void RecalculateMasking()
Method called when Stencil Mask needs to be updated on this element and parents.
bool m_isRebuildingLayout
Anchor dampening prevents the anchor position from being adjusted unless the positional change exceed...
Mesh mesh
The Mesh of this text sub object.
Base class which contains common properties and functions shared between the TextMeshPro and TextMesh...
Definition: TMP_Text.cs:110
TMP_VertexDataUpdateFlags
Flags to control what vertex data is pushed to the mesh and renderer.
override Mesh mesh
Reference to the Mesh used by the text object.
float GetPreferredHeight()
Method to calculate the preferred height of a text object.
Definition: TMP_Text.cs:3563
override Material GetModifiedMaterial(Material baseMaterial)
new RectTransform rectTransform
Returns are reference to the RectTransform
Definition: TMP_Text.cs:1063
override void SetAllDirty()
float GetPreferredWidth()
Method to calculate the preferred width of a text object.
Definition: TMP_Text.cs:3505
override void LoadFontAsset()
Method which derived classes need to override to load Font Assets.
override void InternalCrossFadeColor(Color targetColor, float duration, bool ignoreTimeScale, bool useAlpha)
Tweens the CanvasRenderer color associated with this Graphic.
override void ClearMesh()
Function to clear the geometry of the Primary and Sub Text objects.
override void UpdateMeshPadding()
Function to be used to force recomputing of character padding when Shader / Material properties have ...
override int SetArraySizes(int[] chars)
Method used to determine the number of visible characters and required buffer allocations.
override void RecalculateClipping()
Method called when the state of a parent changes.
override void UpdateMaterial()
new CanvasRenderer canvasRenderer
The Mesh Renderer of this text sub object.
override void InternalCrossFadeAlpha(float alpha, float duration, bool ignoreTimeScale)
Tweens the alpha of the CanvasRenderer color associated with this Graphic.
override void ComputeMarginSize()
Update the margin width and height
override void UpdateGeometry(Mesh mesh, int index)
Function to force the regeneration of the text object.
override void ForceMeshUpdate(bool ignoreInactive)
Function to force regeneration of the mesh before its normal process time. This is useful when change...
override void UpdateVertexData()
Function to upload the updated vertex data and renderer.
override TMP_TextInfo GetTextInfo(string text)
Function used to evaluate the length of a text string.
string text
A string containing the text to be displayed.
Definition: TMP_Text.cs:116
void UpdateSubObjectPivot()
Method to keep the pivot of the sub text objects in sync with the parent pivot.
void CalculateLayoutInputHorizontal()
Function called by Unity when the horizontal layout needs to be recalculated.
TMP_TextInfo textInfo
Returns data about the text object which includes information about each character,...
Definition: TMP_Text.cs:1014