Creative Scripting for Timeline
Timeline is a powerful tool for creating cutscenes and short movies. But there’s more to it! Let’s see how we can leverage Timeline to blend gameplay and storytelling, bringing our game to the next level.
With the release of 2017.1, Unity added a new and powerful tool to its arsenal: Timeline. You have probably seen at this point how creators have leveraged Timeline to create incredible short movies, like Neil Blomkamp’s Adam Episode 2 and 3 or Unity’s own Book of the Dead, or to add storytelling to their games.
This all sounds very exciting, but as a game developer, the question that I asked myself when I saw Timeline was: is it really just a linear sequencing tool? Can I only create cutscenes with it? Interrupt the gameplay, play a non-interactive sequence that advances the story, and resume gameplay?
With this question in mind, I created a small demo to use Timeline in a creative way. I made a little Real-Time Strategy game, in which I used some custom Timeline tracks to achieve a couple of interesting effects. And I found the answer to my question (spoiler): with a little bit of scripting, Timeline can do so much more.
If you want to look into the demo that I created while you read, it can be downloaded here. I called it “A Terrible Kingdom” since it uses the graphic assets of “A Mighty Kingdom”, the demo used in the keynote for Vision Summit 2017. But I remixed them a little bit for the purpose of this demo.
Idea 1 – Stopping the Timeline
Let’s start with a simple scenario. Let’s say I want the Timeline to incorporate a dialogue, and I want it to stop automatically to allow the viewer to read the text on screen. When the Spacebar is pressed, the Timeline resumes.
Since this functionality goes hand in hand with the text on the screen, I created a custom track called Dialogue Track that hooks into the UI Manager of my game. Each clip has as properties the text to display, and a simple boolean to decide whether to stop or not. This is the Inspector of the clip:
Each clip on this track tells the UI Manager to display the dialogue UI, what text, and what size to use. Additionally, it can tell the GameManager to stop the Timeline and passes a reference to which one, so the GameManager – once Spacebar is pressed – knows which Timeline to resume. When the clip ends, it tells the UI Manager to hide the dialogue box.
Pretty simple stuff, but it allows me to quickly build dialogues and decide when to stop, or not! (notice that the dialogue where Andy screams “Oi!” doesn’t stop, because it’s non-important text). Here’s how the Timeline looks like:
Idea 2 – Non-linear Timelines
What if I want to rewind the Timeline? Not at the end (that would be easy: just set it to loop!) but at any arbitrary point, and only when a specific condition is verified. This basically allows for non-linear Timelines: sometimes they go back, sometimes they don’t. You can almost imagine them as if they contained an if-else statement.
In this example, I have created a Timeline that animates a storm: the sunlight dims, flashes appear in the sky, lightning strikes hit the ground, and rain start falling down.
I didn’t just create the storm as one continuous sequence, but I envisioned it as three parts. At the beginning, there’s the “transition in”, while the end has a “transition out” to normal weather. In the middle, I left a section of the Timeline which will play during gameplay. Notice there are no Cinemachine clips, so Timeline gives control back to the regular gameplay camera.
I want the storm to go on as long as those two little monsters are alive. I want Timeline to play the intro, play the gameplay part, and just before hitting the outro, I want it to evaluate a condition: are those two little monster dead? If no, rewind the gameplay part and keep playing. If yes, just play the outro.
Enter the Time Machine Track. Clips here can have two functions. One is to act as named markers (see the first clip), the other is to rewind or fast-forward the Timeline to a specific Marker or time. Let’s call this the “action” of the clip.
The other important property of the clips is the “condition”. It can be always, never (basically muting the clip), or if a group of units is dead. Notice how if the two monster are alive, the Timeline rewinds:
While if they are dead, it just goes on without interruption, playing the outro:
A note: This “is-dead” condition is very specific to my game, but you can come up with something new for your own specific needs, by plugging into the gameplay logic. Has the player reached a certain point? Has the player collected enough of a specific resource? The possibilities are endless!
Now for the result:
The storm starts, then gameplay resumes and the storm goes on, rewinding a couple of times. As you can see, it’s a seamless rewind. Then, once the monsters are defeated – after a couple of seconds – the storm ends and gameplay resumes again.
Idea 3 – Plugging Timeline into the game systems
This is where things get exciting. Until now, we have put our animation on the Timeline. But what if we could defer this animation to some other system in our game? In my little RTS Demo, I have one very important system that’s active all the time: the game AI. This system is responsible of moving units around (by virtue of the NavMesh Agent), of controlling their Animator components and having the the units play the right animations at the right time: walking, idle, attack, or die.
So, say now I want to choreograph a big battle. I have two ways to do it: one is to create dozens of tracks, one for each unit, and then add hundreds of little animation clips: attack, move, attack, move again, attack again, and then die. All of these need to be adjusted in time, and some offset needs to be applied if I want them to match in space. All in all, it’s a lot of work.
The other way is what I did with my AI Command track: this scripted track takes a special type in the binding, that I called “Platoon”. The Platoon is nothing else than a small script with an array of units. When you send a command to the Platoon script, it “broadcasts” the command to all of the units in its array. I actually use it for the selection in the game, creating a Platoon with the selected units to issue mouse commands.
Back to the Timeline. By binding a Platoon to the AI Command track, I’m able to create clips that represent one command: move there and stand still, move there and guard, attack this specific unit, or even… die on the spot! When the Timeline is played, the units belonging to that Platoon will listen to these commands which will take precedence over whatever they were doing before, resulting in the ability to sequence commands on the AI on the Timeline.
Add in a few camera shots (using Cinemachine, of course!), and you have a big battle with dozens of units using just 3-4 AI Command tracks:
Let’s see the result:
Summing it up
I hope to have sparked your curiosity and creativity with this post. Next time you look at Timeline, think: what could I do with it? Create a Quick-Time-Event system? Orchestrate entire battles? Plan the bullet patterns in a Bullet Hell shooter? (I’m seriously thinking of doing it)
There’s so much you can do with Timeline, a little creativity, and some scripting. I would personally love to hear what you come up with here in the comments or on Twitter. Get creating!