- Home /
Closing as duplicate of: https://forum.unity.com/threads/solved-tmp_textinfo-does-not-work-on-a-list-that-is-populated-at-runtime.655969/
Making a forloop wait for previous code to finish before executing without a noticable delay?
I'm writing a function that changes text in TMP, and after the text has changed I want to iterate through the text up to a specific index to change the color of each character.
It seems like the initial part - changing the text- takes too long, so the forloop starts before the text is all replaced.
I don't want to use a coroutine, and I think that async/await may be the answer, but I'm struggling to find a simple example that lets me understand how to use it.
Here is my code:
private void EnterLetter(char typedChar)
{
if (quoteIndex == 0)
{
// Commented out for clarity as irrelevent.
}
if (IsCorrectLetter(typedChar))
{
// Commented out for clarity as irrelevent.
}
else
{
if (currentQuote[quoteIndex] == ' ')
{
UpdateCurrentQuote(currentQuote, quoteIndex, '·');
}
}
}
private void ChangeCharColour(int quoteIndex, bool status)
{
if (quoteOutput.text[quoteIndex] != Convert.ToChar(" "))
{
TMP_TextInfo textInfo = quoteOutput.textInfo;
int materialIndex = textInfo.characterInfo[quoteIndex].materialReferenceIndex;
newVertexColors = textInfo.meshInfo[materialIndex].colors32;
int CharVertexIndex = quoteOutput.textInfo.characterInfo[quoteIndex].vertexIndex;
if (status)
{
newVertexColors[CharVertexIndex + 0] = correctColour;
newVertexColors[CharVertexIndex + 1] = correctColour;
newVertexColors[CharVertexIndex + 2] = correctColour;
newVertexColors[CharVertexIndex + 3] = correctColour;
}
else
{
newVertexColors[CharVertexIndex + 0] = wrongColour;
newVertexColors[CharVertexIndex + 1] = wrongColour;
newVertexColors[CharVertexIndex + 2] = wrongColour;
newVertexColors[CharVertexIndex + 3] = wrongColour;
}
quoteOutput.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
}
private void UpdateCurrentQuote(string quote, int quoteIndex, char newChar)
{
char[] charArr = quote.ToCharArray();
charArr[quoteIndex] = newChar;
currentQuote = new string(charArr);
quoteOutput.text = currentQuote;
ReColour(quoteIndex);
}
private void ReColour(int quoteIndex)
{
for (int i = 0; i < quoteIndex; i++)
{
ChangeCharColour(i, false);
}
}
I want ChangeColour to wait for ChangeText to be completely finished changing the text before it starts, but I don't want to specify how long it should wait with a coroutine. What is the best way for me to do this?
If possible please provide a simple example, I am new to coding.
I edited the question to show the code.
For clarity, the Recolour function runs and works if the last line in UpdateCurrentQuote is commented out, but as soon as this line is uncommented, the Recolour function no longer works.
Answer here:
The content of the TMP_TextInfo gets updated when the text object has been processed / rendered. This occurs late in the update cycle and just before the Camera is rendered in OnPreRender. So for instance, if you were to create a text object in Awake() and set the text to some value and then checked the textInfo, the data contained in the textInfo would be incorrect / nor reflective of the new text since the text object hasn't been processed yet.
Most of the time this is fine as we usually want to wait until the text object has been processed / rendered before trying to manipulate some of its geometry or act on some of the data contained in the textInfo.
When a text object has been processed / rendered, you can use the TMPro_EventManager.TEXT_CHANGED_EVENT to get a callback as used in the example VertexJitter.cs script contained in the TMP Examples & Extras.
However, when there is a need to have the text object updated right away after changing some of its properties, you can use the TMP_Text.ForceMeshUpdate(); to force this update which in turn will update / populate the textInfo with the relevant data.