Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Typewriter effect with rich text tags in Timeline

Discussion in 'Timeline' started by CarlFat, May 5, 2022.

  1. CarlFat

    CarlFat

    Joined:
    Mar 3, 2022
    Posts:
    2
    I'm trying to make a typewriter effect for a playable behaviour in timeline. I got it to not display the rich text tags, but the problem is, the rich text tags still take up the same time as the normal text. How do I get the rich text tags to not take up time?
    Here is the recording:
    problem-clip.gif
    Here is my code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Playables;
    5. using TMPro;
    6.  
    7. public class TypewriterEffectBehaviour : PlayableBehaviour
    8. {
    9.     //public string DefaultText;
    10.     public string DefaultText;
    11.  
    12.     private string checkText;
    13.  
    14.     private bool isRichTextTag;
    15.  
    16.     // called every frame the clip is active
    17.     public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    18.     {
    19.         var textObject = playerData as TextMeshProUGUI;
    20.         if (textObject == null)
    21.             return;
    22.  
    23.         // given the current time, determine how much of the string will be displayed
    24.         var progress = (float)(playable.GetTime() / playable.GetDuration());
    25.         var subStringLength = Mathf.RoundToInt(Mathf.Clamp01(progress) * DefaultText.Length);
    26.        
    27.         checkText = DefaultText.Substring(0, subStringLength);
    28.         char[] line = checkText.ToCharArray();
    29.  
    30.          if(line[subStringLength - 1] == '<' || isRichTextTag)
    31.         {
    32.             isRichTextTag = true;
    33.             if(line[subStringLength - 1] == '>')
    34.             {
    35.                 isRichTextTag = false;
    36.             }
    37.         }
    38.         else
    39.         {
    40.             textObject.text = checkText;
    41.         }
    42.     }
    43. }
     
    forestrf likes this.
  2. akent99

    akent99

    Joined:
    Jan 14, 2018
    Posts:
    588
    I think the logic needs to be more complex than you have. You need to compute the length of the string without tags and use that instead of DefaultText.Length on line 25. Then you have to do something like write your own Substring method, a version that scans along the input string for the specified number of characters, skipping over tags ("<" .. ">") without counting them. So "a<b>cd</b>e" substring length 1 would return "a", length 2 would return "a<b>c" (the "<b>" is not counted), length 3 would return "a<b>cd", 4 would return "a<b>cd</b>e".
     
    CarlFat likes this.
  3. CarlFat

    CarlFat

    Joined:
    Mar 3, 2022
    Posts:
    2
    Got it. Thank you so much!