Skip to content

Instantly share code, notes, and snippets.

@afolk2
Created November 20, 2018 05:48
Show Gist options
  • Save afolk2/c4e1c9dd9e893588eae0e4e2f412bf01 to your computer and use it in GitHub Desktop.
Save afolk2/c4e1c9dd9e893588eae0e4e2f412bf01 to your computer and use it in GitHub Desktop.
Simple TextMeshProUGUI extensions for character color changing
using UnityEngine;
using TMPro;
public static class TextMeshProExtensions
{
/// <summary>
/// Changes the color of a single character to a specified color.
/// </summary>
/// <param name="textMeshProUGUI">The TextMeshProUGUI that contains the text.</param>
/// <param name="charIdx">The index of the character.</param>
/// <param name="color">The new color of the character.</param>
public static void ChangeCharColor(this TextMeshProUGUI textMeshProUGUI, int charIdx, Color color)
{
// Store the TextInfo for readability and access.
TMP_TextInfo tmpInfo = textMeshProUGUI.textInfo;
// Store the starting vertex of this character.
int vertexIdx = tmpInfo.characterInfo[charIdx].vertexIndex;
// Store the materialReferenceIndex of this character for readability.
int materialIdx = tmpInfo.characterInfo[charIdx].materialReferenceIndex;
// Store the Color32 array of the mesh.
Color32[] newVertexColors = tmpInfo.meshInfo[materialIdx].colors32;
// Change the four vertex of this character to the supplied color.
newVertexColors[vertexIdx] = color;
newVertexColors[vertexIdx + 1] = color;
newVertexColors[vertexIdx + 2] = color;
newVertexColors[vertexIdx + 3] = color;
// Indicate that the Colors32 array has changed and update the vertexData
textMeshProUGUI.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
/// <summary>
/// Change the color of a length of text starting at a specified character index.
/// </summary>
/// <param name="textMeshProUGUI">The TextMeshProUGUI that contains the text.</param>
/// <param name="startCharIdx">The index of the starting character</param>
/// <param name="length">The length of the string to change color.</param>
/// <param name="color">The new color of the characters.</param>
public static void ChangeCharColor(this TextMeshProUGUI textMeshProUGUI, int startCharIdx, int length, Color color)
{
// Store the TextInfo for readability and access.
TMP_TextInfo tmpInfo = textMeshProUGUI.textInfo;
// Initialize the following for use in the for loop.
// CharacterInfo of the current character.
TMP_CharacterInfo charInfo;
// MaterialReferenceIndex of the current character.
int materialIdx;
// Starting vertexIndex of the current character.
int vertexIdx;
// Color32 array of the mesh.
Color32[] newVertexColors;
// Loop through the characters starting from startCharIdx and going to startCharIdx + length
for (int i = 0; i < length; i++)
{
// Store the CharacterInfo of the current character.
charInfo = tmpInfo.characterInfo[startCharIdx + i];
// If the current character is not a space. If it is then the vertexIndex is 0 and you will change the color of the first character in the string instead.
if (charInfo.character != ' ')
{
// Get all of the references.
materialIdx = charInfo.materialReferenceIndex;
vertexIdx = charInfo.vertexIndex;
newVertexColors = tmpInfo.meshInfo[materialIdx].colors32;
// Set the vertex colors of the current character.
newVertexColors[vertexIdx] = color;
newVertexColors[vertexIdx + 1] = color;
newVertexColors[vertexIdx + 2] = color;
newVertexColors[vertexIdx + 3] = color;
}
}
// Indicate that the Colors32 array has changed and update the vertexData
textMeshProUGUI.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
/// <summary>
/// Changes the color of the first occurance of the substring within the text.
/// WARNING: THIS IS A WORK IN PROGRESS AND I AM NOT SURE IF WORKING AS INTENDED.
/// </summary>
/// <param name="textMeshProUGUI">The TextMeshProUGUI that contains the text.</param>
/// <param name="substring">The substring to look for.</param>
/// <param name="color">The new color of the substring characters.</param>
public static void ChangeCharColor(this TextMeshProUGUI textMeshProUGUI, string substring, Color color)
{
// Store the TextInfo for readability and access.
TMP_TextInfo tmpInfo = textMeshProUGUI.textInfo;
// Initialize the following for use in the for loop.
// CharacterInfo of the current character.
TMP_CharacterInfo charInfo;
// MaterialReferenceIndex of the current character.
int materialIdx;
// Starting vertexIndex of the current character.
int vertexIdx;
// Color32 array of the mesh.
Color32[] newVertexColors;
// Get the starting index of the substring. Using Ordinal StringComparison for different languages.
int charIdx = textMeshProUGUI.text.IndexOf(substring, System.StringComparison.Ordinal);
// Loop through all of the characters in the substring.
for (int i = 0; i < substring.Length; i++)
{
// Store the CharacterInfo of the current character.
charInfo = tmpInfo.characterInfo[charIdx + i];
// If the current character is not a space. If it is then the vertexIndex is 0 and you will change the color of the first character in the string instead.
if (charInfo.character != ' ')
{
// Get all of the references.
materialIdx = charInfo.materialReferenceIndex;
vertexIdx = charInfo.vertexIndex;
newVertexColors = tmpInfo.meshInfo[materialIdx].colors32;
// Set the vertex colors of the current character.
newVertexColors[vertexIdx] = color;
newVertexColors[vertexIdx + 1] = color;
newVertexColors[vertexIdx + 2] = color;
newVertexColors[vertexIdx + 3] = color;
}
}
// Indicate that the Colors32 array has changed and update the vertexData
textMeshProUGUI.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
/// <summary>
/// Change the color of each vertex of a single character.
/// Four vertex to a character starting from bottom left and continuing clockwise.
/// </summary>
/// <param name="textMeshProUGUI">The TextMeshProUGUI that contains the text.</param>
/// <param name="charIdx">The index of the character</param>
/// <param name="colors">A Color array of size 4.</param>
public static void ChangeCharColor(this TextMeshProUGUI textMeshProUGUI, int charIdx, Color[] colors)
{
// Ensure that the colors array is of the correct size and throw an exception if not.
if (colors.Length != 4)
{
throw new System.Exception("Color array must be of size 4.");
}
else
{
// Store the TextInfo for readability and access.
TMP_TextInfo tmpInfo = textMeshProUGUI.textInfo;
// MaterialReferenceIndex of the character.
int materialIdx = tmpInfo.characterInfo[charIdx].materialReferenceIndex;
// Starting vertexIndex of the character.
int vertexIdx = tmpInfo.characterInfo[charIdx].vertexIndex;
// Color32 array of the mesh.
Color32[] newVertexColors = tmpInfo.meshInfo[materialIdx].colors32;
// Set the vertex colors of the character.
newVertexColors[vertexIdx] = colors[0];
newVertexColors[vertexIdx + 1] = colors[1];
newVertexColors[vertexIdx + 2] = colors[2];
newVertexColors[vertexIdx + 3] = colors[3];
// Indicate that the Colors32 array has changed and update the vertexData
textMeshProUGUI.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment