Page 1 of 1

How do you call a timed function with TypewriterEffect?

Posted: Tue May 28, 2024 5:57 pm
by TiredBoar
Hello,

I've been looking for a way to call functions while the typewriter sets the text in the UI. Specifically, I want to use tags like <function=MyFunction()> in the text, and have the typewriter effect execute these functions at the appropriate times as it types out the text.

I've read through a few posts and looked into Lua, Sequencer, and Event implementation, but couldn't find a solution to my problem, as they all were called at the start or at the end, not while the dialogue was written. If I have overlooked something, I apologize.

My goal is to play different animations and sound effects at specific points or manipulate the typewriter speed for dots "..." as the dialogue gets typed out. Using Invoke for each event and timing them correclty seemed too cumbersome compared to embedding function calls directly within the text.

I attempted to modify the TextMeshProTypewriterEffect, but I couldn't find a way to properly override the text display method. I might be approaching this the wrong way, or perhaps there's already a solution available that I missed. I would greatly appreciate any help or pointers on how to achieve this.

By the way, I've been using the Dialogue System for a few years now and just wanted to say thank you for your hard work.

Code: Select all

using UnityEngine;
using System.Collections;
using PixelCrushers.DialogueSystem;
using TMPro;

public class CustomTextMeshProTypewriterEffect : TextMeshProTypewriterEffect
{
    protected IEnumerator TypeText(TextMeshProUGUI textComponent, string text, float charsPerSecond, float delay)
    {
        int length = text.Length;
        int charIndex = 0;
        textComponent.text = string.Empty;

        while (charIndex < length)
        {
            if (text[charIndex] == '<')
            {
                int endIndex = text.IndexOf('>', charIndex);
                if (endIndex > charIndex)
                {
                    string tag = text.Substring(charIndex + 1, endIndex - charIndex - 1);
                    if (tag.StartsWith("function="))
                    {
                        string functionName = tag.Substring("function=".Length).Trim();
                        ExecuteFunction(functionName);

                        charIndex = endIndex + 1;
                        continue;
                    }
                }
            }

            textComponent.text += text[charIndex];
            charIndex++;
            yield return new WaitForSeconds(1f / charsPerSecond);
        }
    }

    private void ExecuteFunction(string functionName)
    {
        switch (functionName)
        {
            case "MyFunction":
                MyFunction();
                break;
            default:
                Debug.LogWarning("Function not found: " + functionName);
                break;
        }
    }

    // Example function that can be called from within the text
    private void MyFunction()
    {
        Debug.Log("MyFunction was called!");
    }
}

Re: How do you call a timed function with TypewriterEffect?

Posted: Tue May 28, 2024 6:37 pm
by Tony Li
Hi,

You can modify the typewriter effect to handle additional tags (e.g., of your own design), but it might be much easier to use Text Animator for Unity. It can do pretty much everything TextMeshProTypewriterEffect can do and much more, including inserting your own code triggers.

If you do use TextMeshProTypewriterEffect, you can control the speed of full pause characters (e.g., ,!?) and quarter pause characters (e.g., ,;) as well as insert RPG Maker-style timing codes.

Re: How do you call a timed function with TypewriterEffect?

Posted: Wed May 29, 2024 6:48 am
by TiredBoar
I actually have this asset already, but never knew it could do that. Thank you very much for the help :D

Re: How do you call a timed function with TypewriterEffect?

Posted: Wed May 29, 2024 8:01 am
by Tony Li
Glad to help!