How to Tell a Joke With Unity Timeline
Writing jokes is easy. Telling jokes is hard. In this tutorial, you’ll learn about Unity’s Timeline and how to create and deliver your very own punchlines! By JJ Richards.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Tell a Joke With Unity Timeline
25 mins
- Getting Started
- Setting the Scene
- Adding the Text Bubble
- Adding the Comedian
- Revealing Text Over Time
- Understanding Comic Timing
- Understanding Timeline
- Prepping Assets
- Activating GameObjects
- Sending Signals
- Receiving Signals
- Reacting to Signals
- Creating Custom Tracks
- Telling a Joke
- Where to Go From Here?
Receiving Signals
Create JokeReceiver and add the Playables
declaration to the script, above the class declaration:
using UnityEngine.Playables;
In addition to being a MonoBehaviour
, this class also needs to implement INotificationReceiver
, like so:
public class JokeReceiver : MonoBehaviour, INotificationReceiver
Now, create a reference to the Typewriter in the scene:
[SerializeField]
private Typewriter dialogAnimator;
Since the JokeReceiver passes the content of the message to the Typewriter, you need to create a stub function in the Typewriter script to process that message. To do this, switch to the Typewriter script and add:
public void AddDialog(Dialog message)
{
}
You'll populate this function later in the tutorial, but it's helpful to have the stub in place before finishing the JokeReceiver script.
Return to the JokeReceiver script and implement the INotificationReceiver
interface with the following code:
//1
public void OnNotify(Playable origin, INotification notification, object context)
{
//2
if (notification is JokeMarker dialog && dialogAnimator != null)
{
//3
var newdialog = new Dialog
{
//4
Quote = dialog.Quote,
PausePerLetter = dialog.PausePerLetter,
NewPage = dialog.StartNewPage,
NewLine = dialog.StartNewLine
};
//5
dialogAnimator.AddDialog(newdialog);
}
}
Here, you:
- Implement
OnNotify
with the necessary parameters. - Check to make sure the notification is the correct type and not
null
. - Create a temporary variable
newdialog
to store the content of the notification. - Assign the corresponding elements of the notification to the
newdialog
. - Forward
newdialog
to the stub function in the Typewriter.
Save the script and return to the editor. Attach the JokeReceiver script to the JokeText GameObject, then assign the Typewriter component on the same GameObject to the Dialog Animator slot in the Inspector for the Joke Receiver component.
As the message moves from the JokeMarker to the Typewriter, the final step is for the Typewriter to do something with the message.
Reacting to Signals
Return to the Typewriter script and fill out the AddDialog
stub function:
public void AddDialog(Dialog message)
{
//1
timePerCharacter = message.PausePerLetter;
//2
//clear and start new
if (message.NewPage)
{
textBox.maxVisibleCharacters = 0;
textBox.text = message.Quote;
StartCoroutine(Reveal(0));
}
//3
//append to existing
else
{
//4
int currentLetterIndex = textBox.maxVisibleCharacters;
//5
if (message.NewLine)
{
textBox.text = string.Concat(textBox.text, "\n", message.Quote);
}
else
{
textBox.text = string.Concat(textBox.text, " ", message.Quote);
}
//6
StartCoroutine(Reveal(currentLetterIndex));
}
}
With this code, you:
- Update
timePerCharacter
with the value in the message. - Start a new page, if the message requests it.
- If not, add the content of the message to the existing page.
- Capture the current index of what's already been revealed.
- Start a new line, if the message requests it. If not, add the content of the message to the existing line.
- Begin revealing letters, starting at the index provided.
Save the script and return to the editor.
With the Timeline infrastructure in place, you no longer need the test OnEnable
in the Typewriter script. Delete it or comment it out so JokeReceiver is the only thing that calls Reveal()
on the Typewriter script.
Now that all the infrastructure is in place, it's time to tell a joke.
Creating Custom Tracks
Ha ha! The joke's on you. There's one more piece to the puzzle. To keep Timeline neat and tidy, your jokes deserve their own Track. So next, create one more script and name it JokeTrack. It's not much to look at, but it packs quite a punch(line). :]
Add the Timeline
declaration to the script, above the class declaration:
using UnityEngine.Timeline;
Instead of the usual Monobehaviour
, this script needs to derive from MarkerTrack
. So replace the default class definition with:
public class JokeTrack : MarkerTrack
Finally, add two Attributes:
//1
[TrackBindingType(typeof(JokeReceiver))]
//2
[TrackColor(255f/255f, 140f/255f, 0f/255f)]
- Configure the track to work with
JokeReceiver
. - Customize the track UI to any color you want.
Save the script and return to the editor. Now, you're ready to be funny in style. Seriously.
Telling a Joke
Select Timeline in the Hierarchy and make sure the Timeline Window is open so you can see the two Activation Tracks you added previously. Now, drag the JokeText GameObject to the left panel, then select Joke Track to add it to the Timeline.
Next, at the 3:00 second mark, right-click on the JokeTrack and select Add Joke Marker. In the Inspector, populate the content of the message as follows:
-
Quote
There's 10 types of people in the world. -
Pause Per Letter
0.05 -
Start New Page
checked -
Start New Line
unchecked
Add a second JokeMarker at the 7:00 mark with the following content:
-
Quote
Those who know binary, -
Pause Per Letter
0.1 -
Start New Page
unchecked -
Start New Line
checked
Add a third JokeMarker at the 11:00 mark with the following content:
-
Quote
and those who don't! -
Pause Per Letter
0.01 -
Start New Page
unchecked -
Start New Line
checked
Finally, add a fourth JokeMarker at the 14:00 mark with the following content:
-
Quote
01 01 01 01 01 01 01 01 -
Pause Per Letter
0.03 -
Start New Page
checked -
Start New Line
unchecked
After you've added all four markers, your Timeline will look like this:
Save the scene and the project.
Click Play and enjoy the show!
Every comic genius has their own style and pace. Now, you have all the tools to create your own perfect delivery for maximum laughs. Try moving the markers around on the Timeline. Try different pause lengths for each part of the joke. Try different jokes!
Whatever you decide, your comedy career is ready to launch. :]
Where to Go From Here?
Great job on completing this tutorial! You can download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.
Feel free to tweak the project to your needs and turn it into something that gets you laughed at. :]
Besides the obvious use of creating different jokes or an entire set of them, you can use the infrastructure you just built for the JokeMachine for other types of machines, like:
- Cutscene narratives.
- A multi-track system for dialog between characters.
- Adding Animation tracks to the Timeline to make the Comedian bounce up and down when it laughs.
- Moving the Comedian's mouth in time with the Typewriter.
- Even creating your own custom Marker/Receiver/Track system to design and easily tune obstacle patterns in an endless runner.
Timeline is flexible and powerful.
The Unity Timeline will continue to evolve, so follow the latest updates in the Unity Timeline official documentation.
For more examples of things you can do with Timeline, check out the Unity Blog.
I hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!