Skip to content

Tutorials · Animation and Cutscenes · Chapter 7

Root motion

20 minutes Uses: RootMotion, StateMachine, heard, heard_value, held, in_group, pressed, set_number, set_param_flag, state, trigger

By the end

  • A crouch action on S and Down, a crouch switch and a slide trigger in the graph, and three states, crouch, slide and crouched, with their edges: eighteen in all
  • knight.rgs: S crouches him, J slides him from a crouch, and slashes him otherwise
  • The slide’s four pivots, which set how far each frame carries him, and crouched, a one-frame clip that holds the pose the slide ends in
  • A Root Motion on the knight that carries him 48 units along the slide, and stops at a wall
On this page

Crouch and slide

Two more orders. S or Down crouches the knight for as long as it is held, and J while he is crouched slides him instead of slashing. The graph chooses all of it, so the work is three states, a switch, a trigger and their edges, and a few lines in the knight’s script.

  1. Choose View → Input map…. Type crouch into New action and press Add. With crouch selected, press Record a control and press S. Press Record a control again and press Down. Press Save, and close the window.
  2. Select knight and click the Graph tab. In the Parameters list, type crouch into the name box, choose switch in the list of kinds and press Add. Type slide, choose trigger and press Add. The crouch row has a tick box, and it starts unticked.
  3. In the row over the canvas, add three states, each with the State and Clip boxes filled in as crouch and crouch, slide and slide, and crouched and crouched, with Add state. Drag them to a row of their own under the others. The crouched clip is made in the next section; its name is all the state needs now.
  4. Click idle, press Link and click crouch. In the new row, idle to crouch, choose Is and type crouch in the name box, and leave its box ticked: true. Press the + at the end of the row: a second test, which must hold as well. Choose Is, type grounded and leave it ticked. Press the row’s up arrow until its number reads 2: it then comes just after the two Any State arrows. (While idle is selected the list shows only its own arrows; the number is the arrow’s place in the whole list.)
  5. Do the same for run to crouch: the same two tests, and its up arrow until its number reads 3.
  6. Click crouch, press Link and click idle. Choose Is, type crouch and untick the box: false. Click crouch, press Link and click slide: choose Trigger and type slide.
  7. Click slide, press Link and click crouched: choose Finished. Click crouched, press Link and click idle: choose Is, type crouch and untick the box. Click crouched again, press Link and click slide: choose Trigger and type slide. Every blend stays 0.
  8. Press Save.
The Input window with two actions, attack and crouch, crouch selected: two controls, S and Down, each set to Press
The Graph tab on the knight’s graph: the boxes idle, run, hurt, air, land and slash above, and a row of their own under them with crouch, slide and crouched; arrows labelled crouch is true and grounded is true run down from idle and run to crouch, and one labelled crouch is false runs back; trigger slide and finished join crouch, slide and crouched; the Parameters list at the right begins with crouch, a switch with a tick box, and has slide among its triggers
The Transitions list: row 0, Any State to hurt, and row 1, Any State to slash, each when Trigger; row 2, idle to crouch, and row 3, run to crouch, each with two tests, Is crouch, ticked true, and under it, Is grounded, ticked true; then idle to air and run to air when grounded is false, idle to run at 0.10 s when speed is above 10, and the top of run to idle at 0.15 s
The list’s first eight rows of eighteen: the two ways into the crouch are rows 2 and 3, each with two tests.
Switch
A kind of parameter: a tick box. It is on or off and stays as it was set, which is what a trigger is not. crouch starts off. A script sets it with set_param_flag, and a condition reads it with Is.
and
A row can hold several tests, one under another, which the + at the row’s end adds, joined by and: the edge fires only when every one holds. crouch is true and grounded is true is a crouch on the ground, so a crouch in mid-air is not one.

The two ways into the crouch are rows 2 and 3, ahead of the walking edges, for a reason. The keys drive his body, and the graph only chooses the clip, so S and D can be down on one step. From idle, idle → run holds, since his speed is above 10, and so does idle → crouch. The first in the list wins, and a crouch has to. Crouched, A and D still walk him, and the graph keeps him in the crouch clip while they do.

  1. Select knight. In the Code tab, replace everything in knight.rgs with the script below, and press Ctrl+S.
rgs knight.rgs
/// The knight's orders: J or X slashes, unless he is hurt; crouched (S or
/// down), J slides instead. The spikes hurt him, and not again until his
/// hurt clip has played out; its recoil frame lifts him by the number it
/// carries.
component Knight : Area {
    /// Whether his hurt clip is still playing.
    #[hidden]
    hurting: bool = false,

    fn while_in() {
        if in_group(other, "spikes") && !hurting {
            hurting = true;
            trigger("hurt");
        }
    }

    fn on_signal() {
        if heard("frame:recoil") {
            set_number("CharacterBodyComponent", "velocity.y", -heard_value("frame:recoil"));
        }
        if heard("finished:hurt") {
            hurting = false;
        }
    }

    fn loop() {
        set_param_flag("crouch", held("crouch"));
        if pressed("attack") {
            if state() == "crouch" || state() == "crouched" {
                trigger("slide");
            } else if state() != "hurt" && state() != "slide" {
                trigger("slash");
            }
        }
    }
}
held
Whether the player is holding the action down, on every step. pressed is true for the one step the key goes down; held is true for as long as it stays down. held("crouch") is true while S or Down is.
set_param_flag
Sets the switch of that name that this node’s graph reads, from the next step. The script writes it on every step, so the switch always follows the key: down, it is on; let go, it is off, and the edges crouch → idle and crouched → idle stand him up.
state and trigger("slide")
The state the graph was in as the step began. In crouch or crouched, J raises slide and the graph takes it. Anywhere else, J raises slash, unless he is in hurt or already in slide. crouch → slide and crouched → slide are the two edges that read it.

Why the slide snaps back

The slide is a made picture of four frames, each 128 wide and 32 tall. All four draw the same kneeling figure, but each draws it 16 further on in its cell than the one before: the body is on the cell’s left in the first frame, and 48 units to the right in the last. Chapter 1 cut it with every pivot at 0.5, 1, the middle of its frame’s bottom edge, as the Sprite sheet does. The knight’s node never moves, so the picture runs ahead of him by 16 a frame, and when the slide ends he is drawn back where the node is.

Six close pictures of the knight at the lever, side by side: crouched in the first; in the second he has stepped back to the left, over the lever; in the third a little to the right of that; then further right in the fourth and the fifth; and in the sixth he is back to the left, halfway between the second and the fifth
For comparison, the slide with every pivot in the middle, as chapter 1 cut it: steps 256, 260, 264, 268, 272 and 280 of the same run as the strip below, 4.27 to 4.67 seconds in. The picture steps back, runs ahead and snaps back.

The Frames mode shows the same fault in one picture. Its Onion draws the frames either side of the one you are on as faint ghosts, each at its own size and from its own pivot, so a ghost stands where its frame would be drawn. With every pivot in the middle, the ghost of the next frame stands 16 units ahead of the live one.

The editor with the knight selected and framed, on a copy whose slide pivots are all in the middle: the Viewport shows the knight crouched in the slide’s first frame, in full colour, and a fainter second knight a little ahead of him, both inside the large box that outlines the frame’s 128 by 32 cell; the Animation tab below shows the slide clip on its first frame, with Onion lit, and the Inspector shows Clip slide
For comparison, on a copy of the project whose slide pivots are all in the middle and whose knight’s Clip is slide, so that the live frame is the slide’s: Onion lit on the first of the four frames. The ghost of the second stands 16 units ahead of it.

Pivots as drift

The fix is to move the pivot with the body. A frame’s pivot is the point of it that sits on the knight’s node. If each frame’s pivot sits under the body that frame draws, the body stays on the node and the picture no longer runs ahead. And the pivot has moved, 16 units a frame along the picture. That movement is the drift: how far the art has stepped from one frame to the next. Root motion hands it to the node, which moves by it, so the knight is carried as far as the pivots say, in the world.

  1. Select knight, and in the Animation tab open the slide clip. In its Frames, click the first frame and set its pivot x to 0.25, y stays 1. Click the second and set 0.375. The third is already 0.5. Click the fourth and set 0.625.
  2. Double-click art/knight.png in Assets. In the Sprite sheet tab, set Cell to 48 and 48 and Margin to 1929 and 0: the crouch strip’s third and last frame. Drag across the one cell, 0, 0: Selected 1 x 1. Press From selection; name it crouched, 12 fps, Loop; press Generate 1 and Clear.
  3. In the Animation tab, open crouched and set its one frame’s pivot x to 0.625, the slide’s last. Press Save.
The Animation tab in its Frames mode on the slide clip: the clip tabs run from knight to crouched, slide lit, Once chosen, 16.0 fps, four frames in the strip, and under Frames the first frame’s row: dur 0.0625, pivot x 0.25, y 1.00, Region x 2125, y 0, w 128, h 32
The Animation tab in its Frames mode on the crouched clip: crouched lit at the end of the clip tabs, Loop chosen, 12.0 fps, one frame, and under Frames its row: dur 0.08333, pivot x 0.625, y 1.00, Region x 1929, y 0, w 48, h 48

Taken again with the pivots set here, that picture has nothing standing out: each ghost lies exactly under the live frame, since the body does not move on the node. That is what the pivots are for.

Drift is the change of the frame’s pivot, times the frame’s drawn size, times the Root Motion’s Scale. The slide’s frames are 128 wide, and the pivot goes up by 0.125 a frame: 16 units, 48 in all, from 0.25 to 0.625. A held crouch with the same 0.625 leaves him where the slide did.

FileClipFramePivotDrift
knight.animslide00.25, 1—
10.375, 116 units
20.5, 116 units
30.625, 116 units
crouched00.625, 1—

crouched is cut 48 wide, 1 frame, from 1929, 0, at 12 fps, Loop, so that it never finishes: a held pose.

Root Motion

  1. Select knight, press Add component and choose RootMotionComponent. Leave its fields as they come: Scale 1, 0 and Enabled ticked. Press Ctrl+S.
The knight selected, its Inspector narrowed with the search box, root, to its Root Motion: Scale x 1.0, y 0.0, and Enabled ticked; the Viewport looks through the game camera at the stage, with the knight at its left outlined as the selection
Scale
The Root Motion’s Scale: how much of the drift is applied, along each axis. 1, 0 applies all of the sideways drift and none of the vertical. The knight’s jump and fall frames change their pivots’ y, to keep his feet down, and that must not lift him, so y stays 0. A new Root Motion has 1, 0.
Enabled
The Root Motion’s Enabled: whether it applies right now. Ticked, the drift of the frame he is on is added to his move each step. Unticked, the frames still play and nothing carries him. It starts ticked.

The drift is handed to his Character Body as a move that sweeps, as walking is: it stops at what is in the way. A wall in the slide’s path ends the slide there.

  1. Press F5. Hold S, press J and watch the slide carry him. In the Inspector, untick Enabled, and slide again: the frames play, and he does not move. Tick it again, and press F5 to stop.
Six close pictures of the knight at the lever, side by side, with Root Motion off: crouched in the first, and in the same place in all five after it
For comparison, the same slide with Enabled unticked: steps 256 to 280, as in the others. The frames play, and the node stays.

That is the whole of Root Motion. What else the chapter changed is in these tables.

The graph, as the chapter leaves it

KindNameValue
Parametercrouchswitch, starts off
Parameterslidetrigger
Statecrouchclip crouch
Stateslideclip slide
Statecrouchedclip crouched
RowFromToConditionBlend
0Any Statehurttrigger hurt0
1Any Stateslashtrigger slash0
2idlecrouchcrouch is true and grounded is true0
3runcrouchcrouch is true and grounded is true0
4idleairgrounded is false0
5runairgrounded is false0
6idlerunspeed > 100.1
7runidlespeed < 100.15
8airlandfinished0
9landrunspeed > 100.1
10landidlefinished0.1
11slashidlefinished0.05
12hurtidlefinished0
13crouchidlecrouch is false0
14crouchslidetrigger slide0
15slidecrouchedfinished0
16crouchedidlecrouch is false0
17crouchedslidetrigger slide0
NodeComponentFieldValue
knightRootMotionComponentScale1, 0
Enabledticked
FileActionKeys
input.roncrouchKeyS, ArrowDown

Check it works

Six close pictures of the knight’s slide, side by side, cut to the same part of the stage: the lever at the left of each, the knight crouched beside it in the first; in the second he has just begun; he is further to the right in the third, the fourth and the fifth, and by the fifth the wooden lid of the trapdoor is at his right; in the sixth he has not moved from the fifth
The slide, in six steps of one run: S held from step 240, J at 256; steps 256, 260, 264, 268, 272 and 280, 4.27 to 4.67 seconds in. The lever, at 980, does not move: he is carried 48 units.