Search Unity

Question How to prevent TextMeshPro vertex modifications from being reset by maxVisibleCharacter?

Discussion in 'UGUI & TextMesh Pro' started by giresharu, Apr 23, 2023.

  1. giresharu

    giresharu

    Joined:
    Oct 11, 2015
    Posts:
    25
    I wrote a coroutine that implements a typewriter function by incrementing maxVisibleCharacter every certain amount of time. In addition, I also implemented the effect of modifying the vertex color32 in another coroutine. These coroutines are usually called sequentially in a function using StartCoroutine.

    But I found that after changing maxVisibleCharacter in the typewriter function, TextMeshPro would reset all vertex modifications at some point. This sometimes caused other coroutines that modify vertices to fail, even if they were processed every frame in a loop. It cause the text to flicker.

    Below is the code for implementing the typewriter function and a simple coroutine that forces all text color32.a to be set to 123. They are both called in the same function (changing the order of their calls cannot solve the problem):

    Code (CSharp):
    1. IEnumerator TypeWriter(CancellationToken token) {
    2.     typing = true;
    3.     while (visibleCount < textMeshPro.textInfo.characterCount + 1 && !token.IsCancellationRequested) {
    4.  
    5.         if (!isActiveAndEnabled) {
    6.             yield return null;
    7.             continue;
    8.         }
    9.  
    10.         currentChar = visibleCount != 0 ? textMeshPro.textInfo.characterInfo[visibleCount - 1].character : '\0';
    11.  
    12.         if (visibleCount > 0 && ShouldDelay(currentChar)) {
    13.             float startTime = Time.time;
    14.             while ((Time.time - startTime) * 1000 < delay && !token.IsCancellationRequested)
    15.                 yield return null;
    16.             if (token.IsCancellationRequested) yield break;
    17.         }
    18.  
    19.         visibleCount++;
    20.         textMeshPro.maxVisibleCharacters = visibleCount;
    21.     }
    22.     typing = false;
    23. }
    Code (CSharp):
    1. IEnumerator SetTextAlpha() {
    2.     textMeshPro.ForceMeshUpdate();
    3.     TMP_TextInfo textInfo = textMeshPro.textInfo;
    4.  
    5.     List<int> isAppearInRange = IndicesInRange(textInfo, ranges);
    6.  
    7.     while (true) {
    8.  
    9.         foreach (int i in isAppearInRange) {
    10.  
    11.             int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
    12.             int vertexIndex = textInfo.characterInfo[i].vertexIndex;
    13.  
    14.             Color32[] dstColors = textInfo.meshInfo[materialIndex].colors32;
    15.  
    16.             dstColors[vertexIndex].a = (byte)123f;
    17.             dstColors[vertexIndex + 1].a = (byte)123;
    18.             dstColors[vertexIndex + 2].a = (byte)123;
    19.             dstColors[vertexIndex + 3].a = (byte)123;
    20.  
    21.         }
    22.  
    23.  
    24.         textMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
    25.  
    26.         yield return null;
    27.  
    28.     }
    29. }
     
  2. HilamGhost

    HilamGhost

    Joined:
    May 28, 2019
    Posts:
    1
    Did you fixed it?