Search Unity

TextMesh Pro Teletyping with alpha displaying characters out of order

Discussion in 'UGUI & TextMesh Pro' started by hoperin, Jan 21, 2019.

  1. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    So I've created a text reveal / teletype effect that uses the alpha values instead of .maxVisibleCharacters, using a stripped down version of the example posted here -- so instead of characters fading it just processess one at a time from 0 alpha straight to 255 alpha.

    It looked like it was working fine, until I noticed odd behaviour -- every once in a while the text will display characters out of order, so for example the word [story] will become type out like [s r] [s or] [story].
    Slowing down the update speed stops this behaviour.

    heres a 60fps gif of the behaviour

    My code is fairly simple: set the whole overall color to alpha 0, then iterate over each character and set their alphas up to 255.

    You can see commented out that I also tried, every time the visible count was increased to interate over ALL the characters that should already by set to 255 alpha, rather than just the next character, but that had no effect.

    I also shoved in a Debug line for counting out the visibleCharacter values, and it is iterating over them in the correct order, not that that would really make sense if it weren't...

    Thanks in advance!

    Code (CSharp):
    1.         IEnumerator StartAlphaTeletype()
    2.         {
    3.  
    4.             if (m_textMeshPro == null){
    5.                 m_textMeshPro = this.GetComponent<TMP_Text>();
    6.             }
    7.  
    8.             //SET ALL TO TRANSPARENT
    9.             m_textMeshPro.color = new Color(m_textMeshPro.color.r, m_textMeshPro.color.g, m_textMeshPro.color.b, 0);
    10.  
    11.             // Force and update of the mesh to get valid information.
    12.             m_textMeshPro.ForceMeshUpdate();
    13.  
    14.             TMP_TextInfo textInfo = m_textMeshPro.textInfo;
    15.             int totalCharacters = m_textMeshPro.textInfo.characterCount; // Get # of Total Character in text object
    16.             int visibleCount = 0;
    17.        
    18.             reading = true;
    19.  
    20.             Color32[] newVertexColors;
    21.  
    22.             yield return new WaitForSeconds(textReadSpeed);
    23.  
    24.             while (reading && visibleCount < totalCharacters){
    25.  
    26.                 if (!Mgr_PlayState.Instance.Paused){
    27.  
    28.                     int i = visibleCount;
    29.  
    30.                     //for ALL CHARACTERS UP TO THIS POINT
    31.                     //for (int i = 0; i <= visibleCount; i++){
    32.  
    33.                         // Get the index of the material used by the current character.
    34.                         int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
    35.      
    36.                         // Get the vertex colors of the mesh used by this text element (character or sprite).
    37.                         newVertexColors = textInfo.meshInfo[materialIndex].colors32;
    38.  
    39.                         // Get the index of the first vertex used by this text element.
    40.                         int vertexIndex = textInfo.characterInfo[i].vertexIndex;
    41.  
    42.                         // Set all to full alpha
    43.                         newVertexColors[vertexIndex + 0].a = 255;
    44.                         newVertexColors[vertexIndex + 1].a = 255;
    45.                         newVertexColors[vertexIndex + 2].a = 255;
    46.                         newVertexColors[vertexIndex + 3].a = 255;
    47.  
    48.                    // }
    49.                  
    50.                     Debug.Log(visibleCount);
    51.                     visibleCount += 1;
    52.  
    53.                     m_textMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
    54.  
    55.                     if (visibleCount >= totalCharacters)
    56.                     {
    57.                         ShowAllText();
    58.                     }
    59.                 }
    60.  
    61.                 yield return new WaitForSeconds(textReadSpeed);
    62.             }
     
    Last edited: Jan 21, 2019
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Most likely you are not filtering out characters that are not visible. As a result, you end up using the characterInfo of an invisible character but end up modifying the geometry of one of the visible character.
     
    hoperin likes this.
  3. hoperin

    hoperin

    Joined:
    Feb 9, 2014
    Posts:
    52
    Ah, Thanks! That was indeed the issue in the end -- it took a while of wrangling for me to understand, based on the script I was referencing, how to implement it in my while loop without causing the loop to get permanently stuck, but everything works perfectly now and it doesnt conflict with my vertex jitter scripts either!


    Code (CSharp):
    1.             while (reading && visibleCount < totalCharacters){
    2.  
    3.                 if (!Mgr_PlayState.Instance.Paused){
    4.  
    5.                     int i = visibleCount;
    6.                    
    7.                     //if not visible, skip and up the visible count (or else the while loop will get stuck!)
    8.                     if (!textInfo.characterInfo[i].isVisible){
    9.                         visibleCount += 1;
    10.                     } else {
    11.                    
    12.  
    13.                         // Get the index of the material used by the current character.
    14.                         int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
    15.                         // Get the vertex colors of the mesh used by this text element (character or sprite).
    16.                         newVertexColors = textInfo.meshInfo[materialIndex].colors32;
    17.                         // Get the index of the first vertex used by this text element.
    18.                         int vertexIndex = textInfo.characterInfo[i].vertexIndex;
    19.  
    20.                         // Set all to full alpha
    21.                         newVertexColors[vertexIndex + 0].a = 255;
    22.                         newVertexColors[vertexIndex + 1].a = 255;
    23.                         newVertexColors[vertexIndex + 2].a = 255;
    24.                         newVertexColors[vertexIndex + 3].a = 255;
    25.  
    26.                         //}
    27.  
    28.                         visibleCount += 1;
    29.                         m_textMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
    30.  
    31.                         if (visibleCount >= totalCharacters)
    32.                         {
    33.                             ShowAllText();
    34.                         }
    35.                     }
    36.                 }
    37.  
    38.                 yield return new WaitForSeconds(textReadSpeed);
    39.             }  
     
    sed and Stephan_B like this.