Unity – Simple dialogue with correct word-wrapping

I ran into an issue with getting the correct word-wrap behavior in Unity using the Canvas Text UI element. I wanted to create a simple dialogue system that added characters of a string a bit at a time in order to simulate character speech, a common-enough request. However, with Horizontal Overflow set to Wrap, line-breaks are added when the word flows outside the box. And since Unity doesn’t know how long the rest of the word is, the word jumps to the next line in the middle of writing, which looks weird.

I adapted the following solution based off an answer found here. I set a total duration for the entire dialogue text to complete, and I find the index of the separator between visible text and invisible text. Then, with Rich Text enabled, I add the “color” tag, which sets the color of the rest of the text to 0 opacity.

private IEnumerator _PlayDialogueText(string text, float duration)
{
    float timer = 0;
    int separator = 0;
    m_text.text = "";

    while (timer < duration)
    {
        // Find midpoint in string.
        separator = (int)Mathf.Lerp(0, text.Length, timer / duration);

        // Divide string in 2 and add color at separator.
        string left = text.Substring(0, separator);
        string right = text.Substring(separator, text.Length - separator);
        m_text.text = left + "<color=#00000000>" + right + "</color>";

        timer += Time.deltaTime;
        yield return null;
    }

    m_text.text = text;
}

Now the Text element knows the length of each word in the string; it just doesn’t display the latter half.

Admittedly, this isn’t the most friendly solution in terms of garbage collection, but it’s simple enough to implement on a first pass. I’d love to hear a smarter implementation, perhaps using StringBuilder?

Leave a Reply

Your email address will not be published. Required fields are marked *