Gamasutra: The Art & Business of Making Gamesspacer
View All     RSS
February 20, 2018
arrowPress Releases






If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Better text reveals (Unity code inside)

by Miguel Santirso on 01/29/18 10:10:00 am   Featured Blogs

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

Tutorial texts, dialogs, user interfaces... Revealing text (often known as typewriter effect) is present in most games yet is often overlooked. I have been working on a text-based project recently and I wanted to share some tips based on this experience.

The naive approach

When facing this problem for the first time, I'm sure most programmers do something very similar to this:

public class TextRevealer : MonoBehaviour {

	public Text text;
	
	void Start () {
		StartCoroutine(RevealText());
	}
	
	IEnumerator RevealText() {
		var originalString = text.text;
		text.text = "";

		var numCharsRevealed = 0;
		while (numCharsRevealed < originalString.Length)
		{
			++numCharsRevealed;
			text.text = originalString.Substring(0, numCharsRevealed);

			yield return new WaitForSeconds(0.07f);
		}
	}
}

Which produces this effect:

It could work as a first step, but we can make it better!

Step 1: Ignore spaces

This is the easiest problem to solve but also the most subtle in this example. In longer texts it can be quite noticeable and annoying: Notice how the rhythm of the words appearing is not completely smooth? It seems there are small pauses that make the effect less clean.

Spaces are the culprits; they are invisible and create unnecessary pauses when "revealed". Two extra lines in the previous code fix the problem:

public class TextRevealer : MonoBehaviour {

	public Text text;
	
	void Start () {
		StartCoroutine(RevealText());
	}
	
	IEnumerator RevealText() {
		var originalString = text.text;
		text.text = "";

		var numCharsRevealed = 0;
		while (numCharsRevealed < originalString.Length)
		{
			while (originalString[numCharsRevealed] == ' ')
				++numCharsRevealed;

			++numCharsRevealed;

			text.text = originalString.Substring(0, numCharsRevealed);

			yield return new WaitForSeconds(0.07f);
		}
	}
}

And this is how it looks:

The change is not so obvious in this short text and with the lower framerate of these GIFs, but it does make a difference.

Step 2: Words shouldn't jump between lines

Notice how the word "little" jumps from the first to the second line? This is a more serious problem but also harder to fix... And many games decide to keep it like that.

I think the fix is worth the effort, especially if your game has a lot of text. It's easier to read feels more professional:

See how words don't jump between lines anymore? Our code knows the full text from the beginning and we can make it smart enough that words appear right where they should from the first to the last letter.

There are other ways to achieve this but in Unity we can simply use the HTML text feature. The picture below explains the trick; you should be able to figure out the code.

Step 3: Fade in

Do this when you want to go the extra mile:

Letters start appearing slowly to draw the attention of the reader. Then, they start fading in more quickly until it starts slowing down to signal that the paragraph is ending. It's almost like words are caressing you from the screen...

Again, there are probably better ways to do this but the HTML text trick works here as well and in our project doesn't seem to affect performance in a noticeable way. This picture shows how it works in detail:

Writing the code for this can be a bit trickier, even more, if you want to support additional features like skipping the animation when the reader impatiently taps on the screen. I decided to provide the source code from my latest project to make it easier for you:

TextRevealer.cs at Gist

Feel free to use it and improve it if needed.

Why all the effort?

Some of this tips may not be needed depending on the kind of game you are creating.

In my case, all of this was needed to create La Última Flor de Lazlar, an immersive story composed mostly of text. Revealing text in a nice and appealing way was one of the keys to making it look great.

I needed to work on these details with two goals in mind: Text should be revealed in a way that helps reading and it should convey a bit of the bigger-than-life, almost magical tone of the story.

This is how it looks in-game:

Follow me on Twitter if you like what I write :)


Related Jobs

Infinity Ward / Activision
Infinity Ward / Activision — Woodland Hills, California, United States
[02.20.18]

UI Engineer
QC Games Inc.
QC Games Inc. — Austin, Texas, United States
[02.19.18]

Tools/Infrastructure Software Engineer
Intel
Intel — Folsom, California, United States
[02.19.18]

Graphics/Software Engineer
Rockstar India
Rockstar India — Bangalore, India
[02.19.18]

Lead Programmer





Loading Comments

loader image