Skip to content

Overlay system

An overlay is a pose layered on top of locomotion. The legs keep walking, running and turning with motion matching; the overlay decides how the upper body is held: a rifle at the ready, a torch held up, a box carried in both arms, hands tied, an injured stance. This is the layering approach of the Advanced Locomotion System (ALS), on the Game Animation Sample.

There are two independent overlays:

  • Overlay pose: what the character holds or how it holds itself. Item poses come from the equipment system; stance poses (Default, Injured, HandsTied) from the overlay menu.
  • Overlay body: a body style applied to the whole figure: Default, Masculine, Feminine.
Folder /GASPALS/Systems/OverlaySystem
Component AC_OverlaySystem (on both pawns)
Layer interfaces ALI_OverlayPose, ALI_OverlayBody, ALI_OverlayFirstPerson
Pose Anim Blueprints OverlayPose/ABP_OverlayPose_Base and children ABP_Overlay_<Item>
Body Anim Blueprints OverlayBody/ABP_OverlayBody_Base and children (Default, Masculine, Feminine)
First-person poses FirstPerson/ABP_OverlayFirstPerson_Base and children (Rifle, Pistol2H, Bow)
Blending ABP_LayerBlending (linked into both character Anim Blueprints)
Menus UI/OverlayPose/W_Switcher_Pose, UI/OverlayBody/W_Switcher_Body
Input V (hold, pose menu), B (hold, body menu), mouse wheel / D-pad
Settings Overlay reference

How it works

The character Anim Blueprints call two linked anim layers, OverlayPose and OverlayBody. Which Anim Blueprint implements them is decided at runtime with Link Anim Class Layers on the character mesh:

  • AC_OverlaySystem links ABP_Overlay_Default, _Injured or _HandsTied for the overlay pose menu, and ABP_OverlayBody_<Style> for the body.
  • AC_EquipmentSystem links the item's pose (ABP_Overlay_Rifle...) from its data asset.

The last link wins: equipping an item replaces a stance pose, and choosing a stance in the menu replaces the item pose. At spawn the equipment system initializes after the overlay system and links its pose last (Unequip links ABP_Overlay_Default), so an Overlay Pose set on the pawn's component is replaced. Pick overlays through the menu or Select|NewOverlayPose once the pawn has spawned. Overlay changes are instant (no transition animation plays). Each linked Anim Blueprint outputs a pose; ABP_LayerBlending blends it onto locomotion per body part using curves. See Animation pipeline for where this sits in the full graph.

Pose Anim Blueprints

ABP_OverlayPose_Base holds the logic; its children only hold data. A state machine (SM_OverlayPose) chooses between three states:

State Meaning Enters when
Relaxed Item lowered Start state. From Ready: when sprinting, after 2 s of moving, or after 3 s.
Ready Item raised, not aiming From Relaxed: aim pressed (and not sprinting). From Aiming: aim released or sprint, after at least 0.75 s of aiming.
Aiming Aiming From Ready: aim held, once Ready is a quarter blended in.

With Can Aim off (box, barrel, default and the stance poses), the machine stays in Relaxed. Within each state, the pose is picked by stance (stand, crouch) and speed:

Variable (class defaults of the child) Used for
Stand_Relax_Idle, _Walk, _Run, Stand_Relax_Sprint Standing, relaxed
Stand_Ready_Idle, _Walk, _Run Standing, ready
Stand_Aim_Idle, _Walk, _Run Standing, aiming
Crouch_Relax_Idle, _Move; Crouch_Ready_Idle, _Move; Crouch_Aim_Idle, _Move Crouched
Stand_Aim_Sweep, Crouch_Aim_Sweep Additive aim sweep: arms up and down with the aim pitch

Each pose variable is a Struct_OverlayCurves: an animation (usually a single-frame pose) and a curve map (curve name to value). The pose Anim Blueprint writes the curve map onto the pose, and ABP_LayerBlending reads those curves.

Curves

The curve map decides how much of the body each pose takes over. Names are lowercase:

Curve 0 1
layering_legs, layering_pelvis Locomotion legs and pelvis Overlay legs and pelvis (carry stances)
layering_spine Locomotion spine Overlay spine
layering_spine_add No additive Locomotion spine motion added on top
layering_head, layering_head_add Locomotion head Overlay head / additive
layering_arm_l, layering_arm_r Locomotion arm Overlay arm
layering_arm_l_add, layering_arm_r_add No additive Arm swing added on top of the overlay arm
layering_arm_l_ls, layering_arm_r_ls Arm in mesh space (keeps its aim while the spine moves) Arm in local space (follows the spine)
layering_hand_l, layering_hand_r Locomotion fingers Overlay fingers
enable_handik_l, enable_handik_r Hand IK off Hand IK to the item's HandIK socket
enable_cr_aimoffset Aim offset rig off Aim offset rig on
disable_cr_aimoffset_pitch, _yaw Axis on Axis off

The rifle's ready pose, for reference: all layering_* at 1 except the head and the additive arms (0), right arm local space at 0.5, left hand IK on.

Aim sweep

While aiming, the arms follow the camera pitch through the aim sweep additive, blended by AimSweepValue (the pitch mapped from up to down). Aim Sweep Interp Speed Local (30) and Remote (10) set how fast it follows on the owning machine and on others. See Animation pipeline.

Body Anim Blueprints

ABP_OverlayBody_Base picks one of four poses by stance and movement: Pose Stand Idle, Pose Stand Move, Pose Crouch Idle, Pose Crouch Move. The children set those four animations.

First-person poses

ABP_OverlayFirstPerson_Base has the same pose variables (without the aim sweeps) for the first-person arms, with curves for the first-person rigs. The equipment data's Overlay Pose FP links it. See First person.

The menus

Hold V (pose) or B (body): the world slows to 0.35, a menu with one entry per enum value opens, the mouse wheel or D-pad moves the highlight, and releasing the key selects it. The entries come from Enum_OverlayPose (Default, Injured, HandsTied) and Enum_OverlayBody (Default, Masculine, Feminine).

If the pawn is destroyed while a menu is open, the component's EndPlay calls CloseOverlayMenus: it closes both menus, removes their widgets and sets the world speed back to normal.

Shipped overlays

Overlay pose Can aim First-person version
ABP_Overlay_Default no
ABP_Overlay_Injured no
ABP_Overlay_HandsTied no
ABP_Overlay_Rifle yes ABP_OverlayFirstPerson_Rifle
ABP_Overlay_Pistol1H yes
ABP_Overlay_Pistol2H yes ABP_OverlayFirstPerson_Pistol2H
ABP_Overlay_Bow yes ABP_OverlayFirstPerson_Bow
ABP_Overlay_Torch yes
ABP_Overlay_Binoculars yes
ABP_Overlay_Box no
ABP_Overlay_Barrel no

Injured holds one hand to the side and HandsTied keeps the hands behind the back. Their relaxed standing poses use Pose_Injured_Stand / Pose_HandsTied_Stand and their relaxed crouch poses Pose_Injured_Crouch / Pose_HandsTied_Crouch, with the same layering curve values as the box. They are complete examples of a stance overlay: see Add an overlay state. Pistol1H has poses but no equipment slot uses it; link it from a data asset to try it.

Animation modifiers

AnimModifiers/ holds four animation modifiers for authoring: Create_LayeringCurves keys every layering curve (value 1) on an animation, Copy_Curves and Copy_Curves_Pose copy curves from another animation, and Create_Curves creates curves from parameters. Apply them from the animation's Animation Modifiers window. The shipped overlays use curve maps instead, so the modifiers are optional: use them if you prefer layering curves authored in the animations.

Settings

Where Setting Default
AC_OverlaySystem Overlay Pose Default
AC_OverlaySystem Overlay Body Default
Pose children Can Aim, pose variables, aim sweep speeds per overlay
Body children the four body poses per style

Networking

Overlay Pose and Overlay Body are replicated with RepNotify. The owner changes them locally and sends a reliable Server RPC; every machine links the Anim Blueprints in the RepNotify.

Limitations

  • The menus slow the whole world while open.
  • An Overlay Pose set on the pawn is replaced by the equipment pose at spawn (see How it works).
  • The stance poses (Default, Injured, HandsTied) and the item poses share the pose layer, so a stance and an item cannot be combined.
  • Adding a value to Enum_OverlayPose needs a matching case in AC_OverlaySystem.UpdateOverlayPose.
  • Variables added to ABP_OverlayPose_Base do not reach existing children's class defaults: set them on each child.