0

I have a simple coroutine which is printing text by symbol outputing result in TextMeshProUGUI.

IEnumerator TextPrint(TextMeshProUGUI output, string input, float delay, bool skip)
{
        for (int i = 1; i <= input.Length; i++)
        {
            if (skip) { output.text = input; break; }
            output.text = input.Substring(0, i);
            yield return new WaitForSeconds(delay);
        }
        toSkip = true;
}

And I have a task to edit colors of individual characters. To do that I prepared a code that is looking for color tag in input text and activating so-called colorMode (just a boolean).

IEnumerator TextPrint(TextMeshProUGUI output, string input, float delay, bool skip)
    {
        for (int i = 1; i <= input.Length; i++)
        {
            //looking for color tag like <#A63F3F>
            if (i < input.Length - 1 && input.Substring(i, 1) == "<")
            {
                if (i < input.Length - 2 && input.Substring(i+1, 1) == "#")
                {
                    //writing color to storedColor (string variable)
                    int k = 0;
                    storedColor = "";
                    while (input.Substring(i+2+k, 1) != ">")
                    {
                        storedColor += input.Substring(i + 2 + k++, 1);
                    }
                    //removing color tag from input (we don't need to print it)
                    input = input.Remove(i, k + 3);
                    colorMode = true;
                }
            }
            if (skip) { output.text = input; break; }
            typingSound.PlayOneShot(typingClip);
            output.text = input.Substring(0, i);
            if (colorMode)
            {
                output.ForceMeshUpdate();

                //getting necessary info of the last character and changing its color
                var textInfo = output.textInfo;
                var charInfo = textInfo.characterInfo[textInfo.characterCount - 1];
                int meshIndex = charInfo.materialReferenceIndex;
                int vertexIndex = charInfo.vertexIndex;

                //hexToRgb is a function converting hex color to Color32, and it's working fine
                Color32[] vertexColors = textInfo.meshInfo[meshIndex].colors32;
                vertexColors[vertexIndex + 0] = hexToRgd(storedColor);
                vertexColors[vertexIndex + 1] = hexToRgd(storedColor);
                vertexColors[vertexIndex + 2] = hexToRgd(storedColor);
                vertexColors[vertexIndex + 3] = hexToRgd(storedColor);
                
                output.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
            }
            yield return new WaitForSeconds(delay);
        }
        toSkip = true;
    }

But after printing another character using output.text = input.Substring(0, i); vertex colors are being reset back to white. I spent some time trying to find some info of how to save applied vertex colors but found only a solution when it's necessary to update all colors after every update of text. I find this solution bad for perfomance and trying to find something else. So can somebody give some peace of advice of how to do this task correctly?

  • 1
    I think in general it would be better to use Regex for finding the color tags **once** before looping – derHugo Feb 01 '23 at 11:28
  • @derHugo that's a good idea but finding tag is not the reason why vertex colors are being reset, but thanks for advice – Глеб Буткевич Feb 01 '23 at 11:40
  • It would it at least make easier to apply them back again.. you could for instance not use vertex indices at all but stick to the color tags and just keep adding characters from the current Regex group into the current tag until it ends – derHugo Feb 01 '23 at 11:41
  • @derHugo I thought about it too, but in future I need to move individual characters to make animations with them, and I don't think I can do that without vertex, and the problem with reseting vertex position after printing new character would return I guess – Глеб Буткевич Feb 01 '23 at 12:14

0 Answers0