In this article, I will give a walkthrough of a hero animation graph setup for a 3rd person action platformer game along the lines of Ratchet and Clank or Psychonauts (these are purely examples, I have no idea how their animation setups work). The graph I present is based on work done on a couple of action platformer titles over the last 4-5 years, and I’m going to focus on the fundamental elements in the graph. It’s not rocket science: there is really nothing groundbreaking here, and as with most things the devil is in the details: tweaking individual animations and transitions can make a world of difference in the “feel” of the animation experience. I’ll try to add a few notes on key animations as well, as I go through the graph.
The animation graph
I will use a very basic animation graph for the example, limited to very few node types. This makes the graph slightly more convoluted in some areas, but since the node types used are very basic, with limited hidden state, you can probably imagine how they can be turned into more advanced nodes yourself. (Data flows from the right side towards the left side.)
The node types used are:
- Result. This is the final node, and represents the final output that is handed to the renderer and collision system.
- Animation. This is a source animation. Animations can be looped and synched, and I’ll talk more about this later. A few animation nodes actually have animations dynamically inserted into them by the game code, but I’ve kept those to a minimum.
- Blend. A node that blends (crossfades) between two inputs. A blend node can be masked, so it only crossfades certain parts of the skeleton.
- Switch. A switch is in principle just a blend between N inputs, with a strength for each (the strengths will be normalized so they sum to one). The switch node is intended to be in one state, i.e. putting full weight on one of its incoming nodes, but when it changes state, it will smoothly blend from one incoming channel to another.
Basic setup
The basic setup is this:
There are three main sources of animation data. The first is the huge main action switch (MAIN_ACTION) that the hero is performing. This is a full body animation. This can then optionally be blended with an upper body action (UB_ACTION). Notice the little M on the blend node (UPPER_BODY_MIX), indicating that this node is masked, and will only affect the upper body. Finally, the output from that node is optionally blended with a head action (HEAD_MIX). This is fed into the final node, the result node.
First, we’ll look at the child nodes of the main action in turn.
Standing
The simplest action our hero performs is to stand:
He can stand in two ways, selected by the STAND switch. The first is to stand in a relaxed way (STAND_RELAXED), and the other is to be alert, on guard (STAND_ALERT). These are both loops (indicated by the little L), and which is used will typically depend on whether there is danger nearby, if the hero has used his weapon or taken damage recently, or similar in-game events. Typically, alert will revert to relaxed after some seconds of no danger.
Idling
Once in a while, when standing around doing nothing, the hero will perform a random idle action:
I’ve just chosen some silly ones here (YAWN, STRETCH, PICK_NOSE, SCRATCH_BACK), selected with a switch (IDLE), but the idles are both a chance to show off your hero’s personality and have him react to the environment he’s in: if he’s standing in a frozen wasteland, he might want to warm his hands, for example. This means that you might want to control which idle animations are used programatically. Once an idle animation completes, the hero goes back to standing.
Movement
If the player pushes the stick (I’m assuming a standard console controller here), the hero will move. Some games use a distinct turn animation to first align the hero with the direction he’s supposed to move in. For action games with a twitch-feel, this can be a bit annoying, so we simply turn the hero without any animation. The hero is allowed to turn a certain number of degrees per frame, so it might take a few frames before he’s aligned with his direction of movement. We trigger the animation immediately, though, and the turn happens fast enough to hide the dodgy transition sufficiently.
This graph bit covers both “normal movement” and “strafe-style movement”:
We have four basic directions of movement: forward, backwards, left, and right. In normal movement, we’re only using the forward node, as the hero will turn to the right direction and move forward. In target lock/strafe mode, however, we’ll want to keep his direction locked, so he keeps looking at his target, and thus we need animations for moving in the three other basic directions.
For each of the directions, we blend (in the *_SPEED blend nodes) a walk and a run animation (the *_WALK and *_RUN nodes) based on the speed of movement (i.e. how far the stick is moved). These animations are a bit tricky. They are all looping, and each have the same length. They are also synched (indicated by the little S), meaning that they will all be locked to the same position in the animation. Using this, the animations are now created to have the left foot down on the same frame, the right foot on another frame, swing the arms in the same pattern, and so forth. This means that the animations will look a lot better when blended.
Since we can only either be moving forward or backward, and only either left or right, the FWBW_DIR and LTRT_DIR switch nodes selects based on stick quadrants, and the output of these two are then finally blended based on the exact stick direction in the MOVE_AXIS_MIX node.
Since we wanted a twitch feel, the actual movement speed is controlled by the code, not by root motion in the animations. This can lead to a bit of foot sliding now and then, but makes it a lot easier to tweak and control.
Jumping
When the player presses the jump button, he starts a jump, and can, if he presses the button again within the right time window, continue that jump into a doublejump:
Click to enlarge
A simple switch (JUMP) controls triggering and selection of two animations: SINGLEJUMP and DOUBLEJUMP.
The length of the jump animation is typically the take-off, up to the apex of the jump, and then first meters of the fall. If the hero is jumping on to a higher platform, he will land shortly after the apex, so you need to make sure that the hero is in a good pose from which to transition back to movement. This can be a bit tricky if you want to e.g. do a somersault in the doublejump, as you might end up with the hero upside down when he lands on the ground. If the hero’s head bumps into something on the way up, we immediately change his state and go into falling:
Falling
If the hero hasn’t hit the ground by the end of the jump animation (or if he was forced into a falling state, either by hitting his head on something, or simply walking off an edge), he starts falling:
Click to enlarge
A switch node (FALL) controls which kind of falling the hero is doing: for the first meters, he falls in a controlled way (FALL_CONTROLLED), but if the fall continues, he goes into a panic motion instead (FALL_PANIC). If the hero is over water, he’ll go into a dive (DIVE) animation. All three animations are looping animations that are run until the hero is about to land.
Landing
Now the jump or fall is about to end. It is often ideal to detect this shortly before it happens, so the land animations can begin to transition in before contact is made:
Click to enlarge
If the fall was not particularly long, the hero just lands with a quick landing animation (LAND_NORMAL). If he fell from a greater height, we want to squeeze him together for a second with a heavier landing (LAND_HEAVY), typically stopping or limiting his movement for a few seconds. There is a bit of a special case here, as well: often, the player will be pushing forward on the stick during the landing, because he wants the hero to move immediately. We want to allow this, but still express the landing. Therefore, we have a special version of the movement loop, LAND_FW_MOTION, which is basically a walk cycle with the upper body squeezed downward. This animation is looping and synched to the other movment loops. It looks silly played on its own, but it’s only there as a quick transition between the fall and the normal movement animations. Also, if the hero lands on water (after doing a dive), we do a special animation, LAND_WATER.
Finally, we want to sometimes help out the player if he almost made a jump to a platform. If we detect that he almost made it, we go into a forward roll (ROLL) that moves him forward into safety. Typically, we’ll also require that the stick has been kept at a max position (i.e. pushed forward all the time) during the jump for this to kick in.
Swimming
Swimming is pretty straightforward, as it is basically like movement, but without strafing:
Click to enlarge
There’s a blend node, SWIM_SPEED, blending between two looping, synched animations representing forward swimming at different speeds (SWIM_SLOW and SWIM_FAST), and then there are two additional animations. The first one, GET_OUT_OF_WATER, is used when the hero swims onto land, and is basically a short animation transitioning into standing upright. The other is a looping replacement for “standing” on water (TREAD_WATER), used when the stick isn’t being pushed in any direction. Many games allow a single jump when in water, but disable the double jump.
Close combat
The close combat setup looks like this, and features a series of standard strikes, and a ground pound move:
Click to enlarge
When the player starts pressing the strike button, the hero goes into the first attack (STRIKE_1). If the player keeps mashing the button (new button presses, not just holding it down), that strike will continue into the next one, and the next again (STRIKE_2 and STRIKE_3). Typically, the timing is roughly the same for the first two strikes, then a quick pause, and then strike 3, with the third strike having more forward momentum, giving you a rhythm of “strike, strike, gasp, strike!” when attacking. These are basically concatenated animations, selected from the base switch (CLOSE_COMBAT). If the player keeps pressing, we need to restart the sequence from the first strike, but typically we need to change the pose of the hero back to support the first strike. This is done by the STRIKE_CHAIN animation, which is not a strike in itself, but chains series of 3 strikes together.
The strikes typically have a fair bit of forward motion in them, controlled by root motion in the animations. However, we don’t want this “forced forward motion” to move the hero off a platform into a fall, so we dynamically detect if moving him forward would send him into a fall, and if so, simply stop moving him. It can look a bit silly, but it certainly beats falling down all the time.
The ground pound move is triggered from the apex of a jump, either single or double. The hero does a quick twist and strikes downwards (GRPOUND_BEGIN), and then holds that position (GRPOUND_SMASH) as he destroys objects below him, until he finally completes the move when he nears the ground (GRPOUND_END).
For the normal striks, the code will typically figure out who is being targeted and discreetly turn the hero towards that enemy, to make the strikes look better. This is usually not done for the ground pound move. If the game has multiple close combat weapons, there will be a set of animations for each.
Taking damage
This is a real whopper, not because it’s complex, but just because of the number of variations:
Click to enlarge
When the hero takes damage, we determine the main direction (from front, back, left, or right, or “no direction”) and severity. For “normal severity” damage, we blend (in the DMG_*_STRENGTH nodes) between two synched animations (the DMG_*_LIGHT and DMG_*_HEAVY nodes) to find the right amount of reaction. If the damage is heavy enough to knock down the hero, we have 5 special animations to do this (the KNOCK_DOWN_* nodes). Once knocked down, the hero will need to get back up after some seconds, so we have a GET_UP animation as well. There is a similar set of nodes to cover death (the DIE_* set). All is controlled by the TAKE_DAMAGE switch node.
Generic action
There is one final node that doesn’t look like much, but actually is used a lot:
Click to enlarge
This generic node (MAIN_GENERIC) is used by the code to trigger context-sensitive animations. This is used, for example, for pulling levers, pressing buttons, and so forth. The code hooks up the right animation, and switches to this node. Typically, this action is performed in sync with some object (e.g. the lever that is being pulled), so the hero will be forced into a specific position to match the object in the world. We simply do a quick interpolation to the right position and orientation, but you can of course do more advanced things like having the hero walk and turn to the right position.
(A lot of the “play single animation” nodes elsewhere in the graph (e.g. all the death nodes above) could be triggered off this node instead of sitting on the giant damage switch, but for clarity, I didn’t collapse them into using this node.)
That was all the full body states hanging off the main action branch. The upper body is a lot simpler:
Ranged combat
Since ranged combat is typically performed while running around, it only affects the upper body, enabling the hero to be moving or jumping at the same time:
Click to enlarge
Ranged combat animation is a basic switch (RANGED_COMBAT) between three actions. The first is to simply hold your weapon, a looping animation with the weapon pointing forward (HOLD_WEAPON). The second is to fire the weapon, a short animation that includes the reciol (SHOOT), and finally, the weapon can be reloaded (RELOAD). As with close combat, there is a set of animations for each weapon. Some games try to turn the weapon to point exactly in the direction being aimed, but often, if the action is intense, you don’t need to bother with this.
Generic upper body
As with the full body part, there is a generic upper body node for the code to hook into:
Click to enlarge
This node (UB_GENERIC) is typically used for emotes and other actions that must not block movement.
Finally, the head:
Generic head
This node controls only the head (and it’s subparts, like the eyes):
Click to enlarge
This node (HEAD_GENERIC) is again driven by code, and used when the basic head animation should be overridden, typically to track a nearby object (look-at style). Remember to always turn (actually, click) the eyes before you turn the head, and do a very quick blink when you do.
The full graph
Here’s the entire graph:
Click to enlarge
All in all, it looks like a lot, but relatively few nodes end up being active in any given frame, so it’s quite economical. I left out a lot of things, such as balancing on uneven surfaces, almost falling, different damage types, custom transition animations for transitioning between specific states, ledge hanging, IK, and many more details, but this is a proven base to build on — even if some areas can be made more elegant. As indicated by the game examples given in the introduction, it’s intended for a game that doesn’t focus on realism but with twitch-like gameplay that needs snappy responses.
Programmers, make sure you pair up with the animators, as they will have a lot of great insight into what is needed to make this stuff come alive. Animators, make sure you listen to the programmers once in a while — they know what it takes to make it all perform well, be manageable, and fit in memory! Happy graphing! :)