Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

[FIXED] Change color of individual characters in TextMeshPro - Text (UI)

Discussion in 'UGUI & TextMesh Pro' started by Splosions, May 9, 2022.

  1. Splosions

    Splosions

    Joined:
    Apr 29, 2017
    Posts:
    28
    When it comes to Text (UI) objects it looks like Vertex Color does noting, faceColor does change the color, but for the entire material.

    The only way I have found to be able to change color of individual characters in a Text (UI) is to change the text itself IE:
    Code (CSharp):
    1. <color="red">This color is Red
    I have to loop through all the characters and add a color code before each character.
    And I have to do it in Update()

    Code (CSharp):
    1.  
    2. string newText = "";
    3. for (int i = 0; i < m_TextComponent.textInfo.characterCount; i++)
    4. {
    5.     string c = m_TextComponent.textInfo.characterInfo[i].character.ToString();
    6.     newText += "<color=" + Rainbow(characterCount * 5, i + count + (int)Time.deltaTime) + ">" + c;
    7. }
    8. count++;
    9. m_TextComponent.text = newText;
    10.  
    This feels hacky. And it seems to cause problems elsewhere.

    If I try to use a vertex effect via a core routine IE:
    Code (CSharp):
    1.  
    2.     IEnumerator Wobble()
    3.     {
    4.         m_TextComponent.ForceMeshUpdate();
    5.         Mesh mesh = m_TextComponent.mesh;
    6.         Vector3[] vertices = mesh.vertices;
    7.         while (true)
    8.         {
    9.             for (int i = 0; i < m_TextComponent.textInfo.characterCount; i++)
    10.             {
    11.                 TMP_CharacterInfo c = m_TextComponent.textInfo.characterInfo[i];
    12.                 int index = c.vertexIndex;
    13.                 Vector3 offset = Wobble((Time.time + i) / SpeedMultiplier);
    14.                 vertices[index] += offset;
    15.                 vertices[index + 1] += offset;
    16.                 vertices[index + 2] += offset;
    17.                 vertices[index + 3] += offset;
    18.             }
    19.             mesh.vertices = vertices;
    20.             m_TextComponent.canvasRenderer.SetMesh(mesh);
    21.             yield return new WaitForSeconds(0.025f);
    22.         }
    23.     }
    24.  

    after I disable the core routine via StopAllCoroutines(), I am unable to get the colors to work again. I can see the text changing in the TMP editor, but in game the text is frozen.

    So I need to figure out 1 of 2 ways to fix this.

    Get the text to update during a core routine so I can use core routines for all effects.
    Or figure out why the text stops updating after a core routine has run and stopped.

    Thank you
     
    Liderangel and bobsjobisfob like this.
  2. Splosions

    Splosions

    Joined:
    Apr 29, 2017
    Posts:
    28
    HOLY BALLS ON TOAST I DID IT!



    To start......
    I had to check the "Override Tags" box in the TMP. Apparently that allows "Vertex Color" to be used instead of the material color
    upload_2022-5-8_19-7-48.png

    NOW changing the vertex color of the individual letters works in a core routine!

    Code (CSharp):
    1.  
    2.  
    3.     IEnumerator ColorRainbow()
    4.     {
    5.         while (true)
    6.         {
    7.             for (int i = 0; i < m_TextComponent.textInfo.characterCount; ++i)
    8.             {
    9.                 string hexcolor = Rainbow(m_TextComponent.textInfo.characterCount * 5, i + count + (int)Time.deltaTime);
    10.                 Color32 myColor32 = hexToColor(hexcolor);
    11.                 int meshIndex = m_TextComponent.textInfo.characterInfo[i].materialReferenceIndex;
    12.                 int vertexIndex = m_TextComponent.textInfo.characterInfo[i].vertexIndex;
    13.                 Color32[] vertexColors = m_TextComponent.textInfo.meshInfo[meshIndex].colors32;
    14.                 vertexColors[vertexIndex + 0] = myColor32;
    15.                 vertexColors[vertexIndex + 1] = myColor32;
    16.                 vertexColors[vertexIndex + 2] = myColor32;
    17.                 vertexColors[vertexIndex + 3] = myColor32;
    18.             }
    19.             count++;
    20.             m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
    21.             yield return new WaitForSeconds(refreshSpeed);
    22.         }
    23.     }
    24.  
    25.     public static Color32 hexToColor(string hex)
    26.     {
    27.         hex = hex.Replace("0x", "");//in case the string is formatted 0xFFFFFF
    28.         hex = hex.Replace("#", "");//in case the string is formatted #FFFFFF
    29.         byte a = 255;//assume fully visible unless specified in hex
    30.         byte r = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
    31.         byte g = byte.Parse(hex.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
    32.         byte b = byte.Parse(hex.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
    33.         //Only use alpha if the string has enough characters
    34.         if (hex.Length == 8)
    35.         {
    36.             a = byte.Parse(hex.Substring(6, 2), System.Globalization.NumberStyles.HexNumber);
    37.         }
    38.         return new Color32(r, g, b, a);
    39.     }
    40.  
    41.     public static string Rainbow(int numOfSteps, int step)
    42.     {
    43.         var r = 0.0;
    44.         var g = 0.0;
    45.         var b = 0.0;
    46.         var h = (double)step / numOfSteps;
    47.         var i = (int)(h * 6);
    48.         var f = h * 6.0 - i;
    49.         var q = 1 - f;
    50.         switch (i % 6)
    51.         {
    52.             case 0:
    53.                 r = 1;
    54.                 g = f;
    55.                 b = 0;
    56.                 break;
    57.             case 1:
    58.                 r = q;
    59.                 g = 1;
    60.                 b = 0;
    61.                 break;
    62.             case 2:
    63.                 r = 0;
    64.                 g = 1;
    65.                 b = f;
    66.                 break;
    67.             case 3:
    68.                 r = 0;
    69.                 g = q;
    70.                 b = 1;
    71.                 break;
    72.             case 4:
    73.                 r = f;
    74.                 g = 0;
    75.                 b = 1;
    76.                 break;
    77.             case 5:
    78.                 r = 1;
    79.                 g = 0;
    80.                 b = q;
    81.                 break;
    82.         }
    83.         return "#" + ((int)(r * 255)).ToString("X2") + ((int)(g * 255)).ToString("X2") + ((int)(b * 255)).ToString("X2");
    84.     }
    85.  
    86.  
     
    Last edited: May 9, 2022
  3. Kytra

    Kytra

    Joined:
    Aug 3, 2018
    Posts:
    3
    Nice job! This helped me out!
     
  4. benryhenson

    benryhenson

    Joined:
    Dec 21, 2021
    Posts:
    4