Skip to content

Tutorials · Animation and Cutscenes · Chapter 9

Layers

25 minutes Uses: AnimationLayers, PropertyAnimation, StateMachine, set_param_flag

By the end

  • Three more clips in marionette.propanim: idle, a slow sag of the cross and the torso; wave, the left arm; and breath, a rise to add on top
  • Animation Layers on marionette with three rows: base, driven by a graph, arms, masked to the left arm, and breath, Additive at 0.6 and masked to bar and torso
  • scenes/marionette_base.asm: idle and dance, switched by dancing; and marionette.rgs, which flips the switch every three seconds
On this page

Three jobs at once

The marionette dances, and does nothing else. Chapter 8 gave it one clip on one Property Animation, and one clip says one thing at a time. What the marionette needs is three things at once: something that decides whether it rests or dances, a left arm that waves over both, and a breath on top of everything.

Animation Layers play several clips at once, the bottom layer first, each laid over what is under it. A layer says which clip it plays, how much of it counts, whether it replaces or adds, and which nodes it may move. This chapter builds three, each with one of the three jobs.

Three more clips

Each layer plays one clip of marionette.propanim, so there are three to add beside dance. Select marionette, open the Properties mode of the Animation tab and turn Record on, as in chapter 8. Add the clips one at a time: press the + beside the clip tabs, type the name and press Enter. Then take the rows of its table in turn. For each key, type its time into the time box, 0.00 s, beside the Play and Stop buttons, and press Enter, select the node in the Hierarchy, and type its value in the Inspector: a Rotation in degrees, or a Position. The edit is the key. A row begins on Linear, so open its interpolation menu and choose the mode the table names. Some keys hold the value the node already shows, idle’s first keys and wave’s held upper arm among them, and an edit that changes nothing keys nothing: type another number first, then the one you want, and the second replaces the first.

idle

idle is the marionette at rest, 3 seconds long. The cross and the torso sink three units and come back, the legs, which hang from the torso, sinking with it, and the head turns a little. The torso and the bar are keyed together, so the strings stay taut.

TrackMode01.53
torso translationCubic0, -55.30, -52.30, -55.3
bar translationCubic0, -105.30, -102.30, -105.3
head rotationLinear (angle)180186.88180

wave

wave is the left arm, 1 second long. The upper arm is held up the whole time, at 148.97 degrees, and the forearm and the hand swing to and fro on the end of it.

TrackMode00.51
upper_arm_left rotationLinear (angle)148.97148.97148.97
lower_arm_left rotationLinear (angle)28.65-28.6528.65
hand_left rotationLinear (angle)017.190

breath

breath is 2.4 seconds long, a rise of a unit and a half and back. Its keys are different from every other key in the file. They are not places. They are amounts, to be added to wherever the torso and the bar already are.

TrackMode01.22.4
torso translationCubic0, 00, 1.50, 0
bar translationCubic0, 00, 1.50, 0

Record keys what you type, so the breath is keyed by typing the amount where a place would go: select torso and set its Position to 0, 0 at 0, to 0, 1.5 at 1.2 and to 0, 0 at 2.4, and the same on bar. Record leaves the torso where it stands, so nothing needs putting back.

Last, press Capture RESET again. The RESET clip is what stands under every clip that does not key a property, and it must know about every property any of the clips keys. It now holds twelve tracks: the eight turns of the dance and four more, the torso and the bar at their places, the head turned 180 and the left hand at 0. It writes the values the nodes were built with, not the pose at the playhead. Then turn Record off and press Save in the bar.

The Animation tab on its Properties mode with marionette selected. The clip tabs read dance, RESET, idle, wave and breath, with breath lit, and the playhead reads 1.20 s. Two rows, torso translation and bar translation, both on Cubic, each with three diamonds at 0, 1.2 and 2.4 on the ruler, and a thin line at 1.2
breath at its peak, 1.2 seconds in. The clip is 2.4 long.

A stack of layers

The layers go on marionette itself, in one list. The list runs from the bottom layer up: the first row is the base, and each row after it is laid over the rows before it.

  1. Select marionette, click Add component and choose AnimationLayersComponent.
  2. Press the + beside Layers three times. Open each row with the arrow at its left.
  3. In [0] set Name to base and Clip to idle: the row reads 1 base from now on, its place and its name. Leave Weight at 1 and Blend on Override. Graph waits for the next section.
  4. In [1] set Name to arms and Clip to wave. Leave Weight at 1 and Blend on Override. Under Mask Nodes press + three times and type upper_arm_left, lower_arm_left and hand_left, one in each.
  5. In [2] set Name to breath, Clip to breath, Weight to 0.6 and Blend to Additive. Under Mask Nodes press + twice and type bar and torso.
The editor with marionette selected and framed, its Inspector narrowed with the search box, layers, to its AnimationLayersComponent, Layers 3 items, all three rows open. Row 0: Name base, Clip idle, Graph marionette_bas… , Weight 1.000, Blend Override, Mask Nodes 0 items. Row 1: Name arms, Clip wave, Graph none, Weight 1.000, Blend Override, Mask Nodes 3 items, upper_arm…, lower_arm… and hand_left, cut short by the field’s width. Row 2: Name breath, Clip breath, Graph none, Weight 0.60, Blend Additive, Mask Nodes 2 items, bar and torso. The Viewport shows the marionette large on its cross
The three rows. The Graph of base is the next section’s.
Layers
The Animation Layers’ Layers: the rows, bottom first. The first row is the bottom layer, and each later row is laid over the rows before it. The marionette’s are base, arms and breath, which the rows read as 1 base, 2 arms and 3 breath.
Name
A layer’s Name: what a script calls it. A script reaches a row’s fields by it: layers.arms.weight is the arms layer’s Weight.
Clip
A layer’s Clip: the clip it plays, by name. All three are property clips of marionette.propanim. With a Graph on the row it is the clip the layer starts on, until the graph chooses another.
Graph
A layer’s Graph: the .asm that drives the layer, or none. The State Machine’s Graph is the same kind of file, and chapter 2 built one: on a node’s own State Machine it chooses the sprite’s clip, and on a layer it chooses the layer’s. A layer with one plays whichever clip the graph’s state names. base has one, made in the next section; arms and breath have none and play their Clip all the time.
Weight
A layer’s Weight, from 0 to 1: how much of the layer counts. At 1 an Override layer replaces what is under it and an Additive layer adds all of its values. At 0 the layer is off. At 0.6 the breath adds three fifths of itself.
Blend
A layer’s Blend: Override lays the layer’s values over what is under it, by its Weight, and Additive adds them to it, by its Weight. Additive means something only to property clips: a layer of sprite frames ignores it. The breath is the one Additive layer.
Mask Nodes
A layer’s Mask Nodes: the names of the child nodes this layer may move. Empty means every node. arms may move only the left arm’s three bones, so the right arm is the base’s; breath may move only bar and torso.

A graph on a layer

The base layer has two states to be in. It rests, and it dances. Chapter 2 built a graph for the knight and chapter 5 gave it parameters a script raises. A layer can have a graph too. It is the same tool, a .asm that decides which clip is playing, but it decides the layer’s clip, not the sprite’s.

  1. Select marionette and open the Graph tab. The bar holds a picker of the node’s graphs, one for each layer. It opens on Layer: base, which has no graph yet and says so.
  2. Press New state machine. It writes scenes/marionette_base.asm and fills the base row’s Graph. The new machine has one state, idle, playing the clip of that name.
  3. In the row over the canvas, type dance into the State box and dance into the Clip box, and press Add state. Drag the new box to the right of idle, so that the edges between them have room for their words.
  4. Under Parameters type dancing, set the kind to switch and press Add. It starts off.
  5. Select idle, press Link and click dance. In the transition’s row choose Is, type dancing in the name box, and leave its box ticked: true. Set its blend to 0.3.
  6. Select dance, press Link and click idle. Choose Is, type dancing in the name box, and untick its box, so that it reads false. Set its blend to 0.3. Press Save in the Graph tab’s bar, and Ctrl+S.
The Graph tab on marionette with the base layer’s slot empty. The bar reads marionette and a Layer: base menu, open, listing Layer: base, Layer: arms and Layer: breath. Below it a blank panel at the right is headed No graph yet, and says that a new machine starts with one state, idle, and nothing else, with a New state machine button
The Graph tab before the base layer has a graph. The picker lists a slot for each layer.
The Graph tab on the base layer. The bar reads marionette, Entry: idle and Layer: base. The canvas shows a dashed Any State box at its top left, a box idle with a green dot, and to its right a box dance, with an arrow each way between them labelled dancing is false, 0.30 s, and dancing is true, 0.30 s. At the right, a Parameters section lists dancing, a switch, unticked, with a name box, a kind menu and an Add button, and a Rehearse section has a dancing box, Step and Restart, and says In: idle
The base layer’s graph. Any State has no edges.

A graph on a layer reads the node’s parameters, the way the knight’s did, and nothing in the scene raises dancing. A script does, and it is the whole script: the marionette rests for three seconds, dances for three, and goes on, turn and turn about. In Assets press Create, choose New script, type marionette and press Enter. In the Code tab replace everything in marionette.rgs with the script below and press Ctrl+S. Then select marionette, click Add component and choose Marionette. It shows no field: clock and dancing are hidden, kept by the script, and start at 0 and off.

rgs marionette.rgs
/// The marionette's puppeteer: it rests three seconds, then dances three,
/// turn and turn about, by the switch its base layer's graph reads.
component Marionette {
    /// Seconds into this turn.
    #[hidden]
    clock: f32 = 0.0,
    /// Whether it dances this turn.
    #[hidden]
    dancing: bool = false,

    fn loop() {
        clock += dt;
        if clock >= 3.0 {
            clock = 0.0;
            dancing = !dancing;
            set_param_flag("dancing", dancing);
        }
    }
}
clock and dancing
Two fields, both #[hidden], since they are the script’s own counting and not something to set. clock is the seconds into this turn, dancing whether this turn is a dance.
clock += dt
dt is the seconds since the last step, so clock counts up in real seconds. At 3 it starts again from 0 and dancing turns over.
set_param_flag
Sets the switch dancing that this node’s State Machine and layers read, from the next step. It is the switch the graph declared, so the base layer’s two edges, dancing is true and dancing is false, are the ones it throws. The script calls it once a turn, when dancing changes.

The layers decide

The layers and the graph

The layers

RowFieldValue
1Namebase
Clipidle
Graphmarionette_base.asm
Weight1
BlendOverride
2Namearms
Clipwave
Weight1
BlendOverride
Mask Nodesupper_arm_left, lower_arm_left, hand_left
3Namebreath
Clipbreath
Weight0.6
BlendAdditive
Mask Nodesbar, torso

The base graph

WhatValue
Entryidle
Statesidle playing idle, dance playing dance
Parameterdancing, a switch, starting off
Transition 0idle to dance, dancing is true, blend 0.3
Transition 1dance to idle, dancing is false, blend 0.3

The script

NodeComponentFieldValue
marionetteMarionetteclockhidden, starts 0
dancinghidden, starts off

Every other field is as it comes.

Check it works

The marionette is at rest for its first three seconds, and then dances for three. In the strip it is at rest, its head turning a little, and the left arm is up, its forearm waving to and fro.

Eight frames of the marionette side by side, from the cross down to the shins, the boards and the feet out of view. In every frame the arm at the left of the picture is raised and bent at the elbow, the forearm leaning a little to one side and the other from frame to frame; the other arm hangs at its side, and the head is turned slightly one way and the other
The wave: eight frames 8 steps, 0.13 of a second, apart, from step 384 to step 440, which is 6.4 to 7.33 seconds in. The left arm is held up and its forearm swings.
The marionette close up on its cross: its left arm raised and waving at the left of the picture, its right arm swung out and down at the right, and its legs apart with the left foot a little off the boards
The dance with the wave over it, at step 331, 5.5 seconds in: the legs and the right arm dance, the left arm waves.

Look at the feet in the idle. The body sinks by its three units, and the legs hang from the body.

Close up of the marionette’s legs from the hips down, in the idle near its lowest: the two feet stand on the boards with their soles a little below the boards’ top edge, so the feet are drawn over the face of the boards, not on them
The idle near its lowest, step 468, 7.8 seconds in: the soles are a little way into the boards. Chapter 10 plants them.