Search Unity

TextMesh Pro Reveal Effects Through Animating Vertex Positions

Discussion in 'UGUI & TextMesh Pro' started by looytroop, Jul 8, 2020.

  1. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    Hello! I have been trying to create some reveal effects in my game for text to appear with one effect, and lead right into a movement effect afterwards. I initially implemented this utilizing the rich text using things such as voffset tags and whatnot.

    I have ran into an issue with this approach. My current implementation is attached as TextEffect_OLD.gif, and you can see that as the last letters move to align with the other letters, the line height gets shorter, and as a result, the whole line shifts, which looks weird and ugly.


    I recently was made aware of the vertex position animations that can be done in text mesh pro and thought that this approach would solve my issues! However, upon going through the YouTube video linked here explaining how this system works, I cannot seem to get the results that I desire and I am having a hard time understanding how this system works in general. I cannot seem to find any written documentation as to how this system is rendered and what all of the methods do, and if the vertex positions are being overwritten or only temporarily moved for this render only.

    I have so far, split my new attempt into two sections, one that sets the letters above where they normally would be, and then one that is supposed to move them down to their end location one letter at a time. It always seems to jump back to where it was originally, and then it completely misses the mark as to where it is supposed to "land." You can see my attempt gif, it's called TextEffect_NEW.gif. Also, I am not modifying the alpha values in the new effect, to make it easier to see what is going on.

    If anyone has experience with this, or a link to the documentation I should be looking at, this would be great! I did not find the examples in the sample scenes to be sufficient, as they were too basic. I also find the YouTube explanation to high-level and too basic, as this only involves an effect that is permanently playing and is cyclical.

    Thanks so much for your help!
     

    Attached Files:

  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Did not have a chance to follow up until now...

    Whenever the properties of a text object are changed, a new layout pass occurs which resets whatever potential modifications you may have made to the geometry.

    To get around this, you have to potentially track the changes you are making to re-apply to the newly update / reset mesh. For instance, if you were to apply an offset to a given character, every time the text object is changed, the geometry will be reset its initial position so this is where you need to track where you need it to be on the frame to override the reset position.

    Currently, the reset geometry is pushed to the Renderer which you then need to potentially copy and then modify and then push again. This is more efficient than changing the text but it still results in grabbing the mesh already pushed, modifying it and then re-pushing.

    In the latest release of TMP which will be version 1.5.0 for Unity 2018.4 and 2.1.0 for Unity 2019.x and 3.0.0 for Unity 2020.x, I added (as per the suggestion of @tessellation) a new callback that allows you to modifying the geometry before it is pushed to the Renderer. Below is an example of this...

    Just for testing, I implemented a per object event where in OnEnable / OnDisable you would register to this event as follows:

    Code (csharp):
    1.  
    2. private void OnEnable()
    3. {
    4.     m_TextComponent.onPreRenderText += OnPreRenderText;
    5. }
    6.  
    7. private void OnDisable()
    8. {
    9.     m_TextComponent.onPreRenderText -= OnPreRenderText;
    10. }
    11.  
    This requires having a reference to the specific text object whose geometry you wish to modify.

    Then in this OnPreRenderText function, you can modify the geometry as follows.

    Code (csharp):
    1.  
    2. void OnPreRenderText(TMP_TextInfo textInfo)
    3. {
    4.     int characterCount = textInfo.characterCount;
    5.  
    6.     for (int i = 0; i < characterCount; i++)
    7.     {
    8.         int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
    9.         int vertexIndex = textInfo.characterInfo[i].vertexIndex;
    10.         Color color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), 1.0f);
    11.  
    12.         textInfo.meshInfo[materialIndex].colors32[vertexIndex + 0] = color;
    13.         textInfo.meshInfo[materialIndex].colors32[vertexIndex + 1] = color;
    14.         textInfo.meshInfo[materialIndex].colors32[vertexIndex + 2] = color;
    15.         textInfo.meshInfo[materialIndex].colors32[vertexIndex + 3] = color;
    16.     }
    17. }
    18.  
    Since the above code is modifying the geometry contained in the meshInfo before TMP uploads it, there is no need to use the UpdateVertexData function.

    As such this is more efficient as it allows you to modify whatever you want before the geometry is added to the mesh and uploaded.

    P.S. Release of TMP that include this new callback will be available tomorrow.
     
  3. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    Awesome! Thank you for your help. Now that I more properly understand this, I was able to get the effect working with relative ease. Thanks for this, and this new PreRender event looks quite nice as well, thanks for the heads up!
     
    Stephan_B likes this.
  4. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    @Stephan_B Sorry I am just getting around to trying to implement the onPreRender version of the implementation.

    I started writing my code to listen for the onPreRender event and I cannot seem to find the event type. Is there anywhere I can find written documentation about this? What is the data type of m_TextComponent in your example?

    I am in Unity 2018.4.26f1. Thanks!
     
  5. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    OnPreRenderText was added in the latest releases of the TMP package which is version 1.5.1 for Unity 2018.4, version 2.1.1 for Unity 2019.4 and version 3.0.1 for Unity 2020.x.
     
  6. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    This is probably really simple, but how can I upgrade the package? I see 2018 doesn't have the package manager. I tried deleting the TMP folder and re importing from the TMP package from the Window dropdown and I still don't have access to this event. I have also tried right clicking the folder and clicking "reimport"

    Thanks!

    Update, I was able to upgrade TMP by removing all of the TMP folders and then copying the asset folders for my project into a new Unity 2019 project.
     
    Last edited: Oct 15, 2020