Page 1 of 1

[HOWTO] How To: Trigger Events At Specific Characters When Typing

Posted: Tue Jan 11, 2022 10:14 am
by Tony Li
If you need to trigger an event when the typewriter effect reaches a specific point in the text, the easiest way is to use Text Animator for Unity. See Text Animator for Unity Support and Triggering Events While Typing.

If you're using plain Text or TextMesh Pro, here are two alternatives:

1. Write a subclass of UnityUITypewriterEffect or TextMeshProTypewriterEffect. Override the Play() method.

2. Or add a script with an OnConversationLine method to your Dialogue Manager. Locate the position(s) of the custom tags you're using to indicate the events, and compute the time that the event should happen by using the typewriter effect's charactersPerSecond value. Example:

Code: Select all

void OnConversationLine(Subtitle subtitle)
{
    // Does the text contain the special tag [Shake]?
    int shakePos = subtitle.formattedText.text.IndexOf("[Shake]");
    if (shakePos != -1)
    {
        // Remove the tag from the text:
        subtitle.formattedText.text = subtitle.formattedText.text.Remove(shakePos, "[Shake]".Length);
        
        // Determine when the typewriter would reach that tag: (Note: Example doesn't account for RPG Maker pause tags.)
        float time = shakePos / DialogueManager.standardDialogueUI.GetComponentInChildren<AbstractTypewriterEffect>().charactersPerSecond;
        
        // Add a sequencer command to do something at that time:
        subtitle.sequence = $"AC(Shake)@{time}; " + subtitle.sequence;
    }
}
That's a simplified version to make it easier to read. It doesn't take into account \. and \, codes or rich text tags such as <b>...</b>. And it only replaces one instance of of the custom tag. Once you get a method like the one above working, you'd want to extend it to handle all that.

Tip: The Tools.StripRichTextCodes() and Tools.StripTextMeshProTags() may be helpful.