I’ve got a text mesh pro text object on a canvas with the following words:
“this is a <link=“Shimmy”>shimmy voodoo test. <link=“SingSong”>sing song adsfasdfasfsafsaf”
private IEnumerator DisplayCharacterByPage(Recitation recitation)
{
// Helper references
TMP_TextInfo textInfo = textScript.textInfo;
int characterCount = textInfo.characterCount;
// Display no characters to start
float appearTimeToWaitTimeRatio = 0.5f;
textScript.text = recitation.GetLocalizedText();
textScript.overflowMode = TextOverflowModes.Page;
textScript.alignment = TextAlignmentOptions.Midline;
textScript.ForceMeshUpdate();
for (int j = 0; j < characterCount; j++) textInfo.characterInfo[j].isVisible = false;
// Apply Emotion
Coroutine emotionCoroutine = StartCoroutine(ApplyEmotion());
// Display characters
float timePerPage = recitation.duration / textScript.textInfo.pageCount;
int charsPerPage = textScript.textInfo.characterCount / textScript.textInfo.pageCount;
int pagesWithExtra = textScript.textInfo.characterCount % textScript.textInfo.pageCount;
// Calculate time to appear
float appearTime = appearTimeToWaitTimeRatio * timePerPage;
// Show characters
int visibleCharacters = 0;
for (int i = 1; i <= textScript.textInfo.pageCount; i++)
{
// Set visible characters
textScript.pageToDisplay = i;
// Show text
int lastCharIndex = i == textScript.textInfo.pageCount ? textScript.textInfo.characterCount : textScript.textInfo.pageInfo[i - 1].lastCharacterIndex;
int charsSoFar = textScript.textInfo.pageInfo[i - 1].firstCharacterIndex;
int charsToAdd = lastCharIndex - charsSoFar;
for (float j = 0; j <= appearTime; j += ClockIncrement)
{
// Fix rounding errors
j = (float)System.Math.Round(j, ClockPrecisionDecimals);
// Set visible characters
float percentPageVisible = Mathf.Min(1f, j / appearTime);
int maxVisibleCharacters = charsSoFar + (int)Mathf.Ceil(charsToAdd * percentPageVisible);
AppearCharacters(ref visibleCharacters, maxVisibleCharacters + 1);
// Wait clock tick
yield return new WaitForSeconds(ClockIncrement);
}
// Wait a wait per page
yield return new WaitForSeconds(timePerPage - appearTime);
}
textScript.text = "";
// Stop the emotion
StopCoroutine(emotionCoroutine);
}
private void AppearCharacters(ref int visibleCharacterIndex, int endIndex)
{
if (endIndex <= 0)
{
return;
}
TMP_TextInfo textInfo = textScript.textInfo;
for (; visibleCharacterIndex < endIndex; visibleCharacterIndex++)
{
// Appear the invisible characters
textInfo.characterInfo[visibleCharacterIndex].isVisible = true;
int vertexIndex = textInfo.characterInfo[visibleCharacterIndex].vertexIndex;
int materialIndex = textInfo.characterInfo[visibleCharacterIndex].materialReferenceIndex;
Color32[] newVertexColors = textInfo.meshInfo[materialIndex].colors32;
Color32 color = newVertexColors[vertexIndex + 0];
color.a = 255;
newVertexColors[vertexIndex + 0] = color;
newVertexColors[vertexIndex + 1] = color;
newVertexColors[vertexIndex + 2] = color;
newVertexColors[vertexIndex + 3] = color;
}
visibleCharacterIndex--;
textScript.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
private IEnumerator ApplyEmotion()
{
TMP_TextInfo textInfo = textScript.textInfo;
while (true)
{
int linkCount = textScript.textInfo.linkCount;
for (int i = 0; i < linkCount; i++)
{
int start = textScript.textInfo.linkInfo[i].linkTextfirstCharacterIndex;
int end = start + textScript.textInfo.linkInfo[i].linkTextLength;
RecitationTextEmotion emotion = (RecitationTextEmotion)Enum.Parse(typeof(RecitationTextEmotion), textScript.textInfo.linkInfo[i].GetLinkID());
string test = "";
for (int j = start; j < end; j++)
{
// Grab Character
TMP_CharacterInfo charInfo = textScript.textInfo.characterInfo[j];
if (!charInfo.isVisible)
{
break;
}
Debug.Log("made it");
test += charInfo.character;
int materialIndex = charInfo.materialReferenceIndex;
int vertexIndex = charInfo.vertexIndex;
Color32 color = new Color32(0, 255, 0, 255);
Color32[] newVertexColors = textInfo.meshInfo[materialIndex].colors32;
newVertexColors[vertexIndex + 0] = color;
newVertexColors[vertexIndex + 1] = color;
newVertexColors[vertexIndex + 2] = color;
newVertexColors[vertexIndex + 3] = color;
textScript.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
Debug.Log(test);
}
yield return new WaitForSeconds(ClockIncrement);
}
If I run this code against that text box starting at DisplayCharacterByPage, characters appear one at a time which is expected. What’s not expected that is also happening is the following words are immediately visible.
“shimmy” “sing”
They show up in green. Once the AppearText function reaches the " " character in “sing song”, the entire word “song” along with the character at index 0 of the entire text immediately turn green.
I’ve read over this code a few times now, so maybe my eyes are just tired and I’m missing something. If so please let me know. Or maybe I’m just not forcing an update of some sort that is required? Otherwise, it might be some sort of bug?

