Action Graph

Documentation Unreal Engine Player Combat Actions

An Action Graph is a character's moveset: each node plays a move, a transition names the input that leads to the next, and a window on the animation says when that input counts.


Chain two attacks on one button

5 minutes
  1. 1

    Create a graph with two moves

    Right-click in the Content Browser, UPC > Actions > Action Graph, name it AG_MyFirstGraph and open it: the canvas holds ROOT, the character standing idle. Right-click the canvas, Add Action Node, twice. Name the cards Light 1 and Light 2 (Node Name) and give both the same Montage, a light attack of your own (AM_Attack_Light here).
    AG_MyFirstGraph
    ▾Action Node Data
    Node NameNone
    Montage
    None▾
  2. 2

    Wire the presses

    Drag from ROOT's right edge to Light 1's left edge, select the router on the wire, and set its Input Tag to UPC.Input.LightAttack; Fires On already reads Input Pressed. Wire Light 1 to Light 2 the same way. A move with nowhere to go returns to ROOT when it ends.
    ROOT
    UPC.Input.LightAttack
    Light 1
    AM_Attack_Light
    UPC.Input.LightAttack
    Light 2
    AM_Attack_Light
    The finished graph: a light attack press leaves Root for Light 1, and another leads on to Light 2.
  3. 3

    Mark when the next press counts

    On AM_Attack_Light, add the UPC Action Window notify state over the frames where the next hit may start. An earlier press waits for it (one at a time); with no window, it waits for the montage's end.
    AM_Attack_Light
    0.0
    0.2
    0.4
    0.6
    0.8
    1.0
    1.2
    1.4
    1.6
    Notifies
    UPC Action Window
    Light attack
    pressed
    Light 2
    The press waits until the window opens, then Light 2 starts.
  4. 4

    Give the graph to an item and play

    A drawn item hands its graph to the character through Action Graph on its Equippable fragment. Use the demo's fists, Item_UPC_Unarmed (Demo/Weapons/Unarmed; tick Show Plugin Content): the demo player fights with them while nothing else is drawn, sending UPC.Input.LightAttack from the left mouse button (right shoulder on a gamepad).
    A character of your own needs an Ability System Component on its PlayerState or pawn (UPC Character Base has one). Save, open Demo/Maps/LVL_UPC_Demo, press Play and click twice. In play, Compile or a save hands an edit to the character; after adding or deleting a card, restart Play. Keep AG_MyFirstGraph on the fists: the Action Graph Editor and Gates, Costs and Cooldowns quick starts build on it.
    Item_UPC_Unarmed
    ▾Equippable
    Action Graph
    AG_UPC_Unarmed▾
The graph deals no damage; a swing lands through a melee trace window on its montage (Melee Trace).

Chain moves into a combo

Mark the window on the montage

The UPC Action Window notify has no settings. With no window, When No Window Is Authored (node Execution) decides: At Completion (default) waits for the montage's end, which suits a combo cut into montage sections; From Entry lets the press cut in at once.

Early and late presses

Select empty canvas to set these on the graph; a node overrides the first two under Execution, Advanced.
SettingDoes
Default Input Buffer ModeWhich press made before the window waits: Accept Last (default) the newest, Accept First the first, Ignore none.
Late Input GraceA press up to 0.25 s after a move runs to its end still follows its links (a click 0.1 s after Light 1 ends plays Light 2). 0 turns it off.
Held Input Restart WindowNot a hold setting. A press only ROOT answers, such as a dodge mid-swing, waits for the move to end, then starts; it expires this long after the press (0.35 s: 0.3 s before the swing ends it plays, 0.5 s before it is forgotten; 0 never expires). Once the swing's action window is open, it drops instead.
Details
AG_MyFirstGraph
Action Graph
Default Input Buffer Mode
Accept Last
Held Input Restart Window
0.35
Late Input Grace
0.25
Select nothing on the canvas and the Details panel shows the graph's own settings.

Choose what a node plays

Pick one Payload per node. The node lasts as long as its payload runs; with none, it ends at once.
PayloadPick it for
Play MontageAttacks, dodges, any animated move. New nodes start with it.
HoldA stance with no animation, such as a block. Lasts until a transition, a cancel or a hook ends it.
DelayA pause inside a combo: Delay Seconds (0.5), then Action Completed.
Trigger Ability / EventA move run by a gameplay ability (a Blueprint ability from an ability set, Items): sends a gameplay event or activates abilities by tag.
Play Paired ActionA finisher or counter with a second character (Paired Actions).
Details
Light 1
Action
Action Node Data
Node Name
Light 1
Costs
0 Array elements
Gates
0 Array elements
Hooks
0 Array elements
Transitions
1 Array element
Execution
Payload
Play Montage
Montage
AM_Attack_Light
Play Rate
1.0
Section Name
None
When No Window Is Authored
At Completion
Spacing
Stop Distance
-1.0
Make Room Seconds
-1.0
Advanced
Input Buffer Override
Use Graph Default
Late Input Grace
0.25
Retrigger From Root On Failed Start
Cancellation
Can be Cancelled
Cancel Window Start
0.1
State
Applied Tags
0 Gameplay Tags
Appearance
Use Custom Color
Select one action card and the Details panel shows that action. Transitions is read only: it fills from the wires when the graph compiles.

Cut a move short

Interrupt transitionCan be Cancelled
WireFrom the swing itself, Timing Interrupt: a parry or dodge out of a committed swing.Wired only from Root, such as a Dodge. Ticked on the swing.
EffectThe press ends the swing and starts the transition's target.An input the swing has no open transition for cuts it and runs from Root: a Dodge press plays the Root dodge.
Waits forCancel Window Start (0.1 s).Cancel Window Start.
Can be Cancelled appliesNo: an Interrupt ignores it and both lists.Yes. Cancellable by Inputs limits cutting tags (empty: any input cuts); Ignored Cancel Inputs bars tags and beats the first list.
Under Can be Cancelled, a move's own input cannot cut it, so mashing attack never restarts a swing. A press before Cancel Window Start waits like any other.
Light 1
AM_Attack_Light
UPC.Input.LightAttack
Light 2
AM_Attack_Light
UPC.Input.Guard
Parry
AM_Parry
Two ways out of Light 1: the light attack waits for its action window, and the guard press, set to Interrupt, leaves for Parry at once.

Branch on more than the button

A transition's Required Tags and Blocked Tags read the character's tags; blocked beats required (a shield's moves require the drawn shield's tag).
Conditions must all pass. They gate a move and spend nothing; a cost on the target node spends (Gates, Costs and Cooldowns).
ConditionPasses when
DirectionThe stick pointed a chosen way at the press: a side step, a lunge.
Vital ThresholdA vital such as stamina is above, below or about a level.
Target StateThe current target carries, or lacks, chosen tags: stunned, open to a riposte.
Target DistanceThe current target is closer than, farther than or about a distance away.
Cooldown ReadyA cooldown has a charge ready.
Paired Action AvailableA paired action from the listed sets can play now.
Of several passing transitions on one input, the highest Priority wins, then the one with more conditions, then the first: a lunge with a Target Distance condition beats a plain strike.

When a move ends or fails

Heavy
AM_Heavy
Auto
Recovery
Failed
Out Of Breath
AM_Tired
Heavy's two ways on: Auto when it finishes on its own, Failed when a cost on it could not be paid.
  • Action Completed leads on when the move finishes with no press waiting: a recovery after a heavy.
  • Action Failed, wired out of a move that could not start (unaffordable cost, closed gate), leads to another move such as a stagger. Without it the press drops and a running move plays on.
  • A move finishing with no press waiting and no Action Completed returns to Root.
A held stance: a press plays the raise, Action Completed leads to a Hold node whose Applied Tags carry UPC.State.Blocking, and Input Released leads from the hold to a To Root card (Add Return To Root on the canvas menu, Action Graph Editor). Wire the release out of the raise too, or letting go mid-raise stays in the guard.
ROOT
UPC.Input.Guard
Guard Raise
AM_Guard_Raise
Auto
Guard Hold
UPC.Input.Guard
UPC.Input.Guard
↩To Root
Zoom -1
A held guard: letting go leads to To Root from the raise and from the hold.

The transition's settings

Details
Transition Router
Transition
Entries
1 Array element
Index [ 0 ]
Fires On
Input Pressed
Input Tag
UPC.Input.LightAttack
Priority
0
Timing
Wait For Window
Required Tags
0 Gameplay Tags
Blocked Tags
0 Gameplay Tags
Conditions
0 Array elements
Select the router on a wire. Each entry in Entries is one transition with an output pin of its own.
Fires OnFires at
Input PressedThe Input Action triggering: the key going down, or a Hold trigger's time completing.
Input ReleasedA release after a press or a completed hold.
Input Released EarlyA release before the trigger completes, such as before a Hold trigger's time.
Action CompletedThe move's own end, with nothing chaining.
Action FailedThe move failing to start.
Input Tag, Priority, Timing and Conditions show for the three input moments only.

Settings on the Action Graph component

Details
ActionGraphComponent
UPC
Action
Global Block Tags
1 Gameplay Tag
UPC.State.ActionsBlocked
Action Speed
1.0
Debug
Debug Overlay Actions
Multiplayer
Dwell Grace Base Seconds
0.1
Max Server Inputs Per Second
20
Created by the character base, with the ability system it needs. A player or an enemy can carry one.
SettingDoes
Global Block TagsShuts the graph while the character carries one (a stagger, a cutscene): presses drop, releases pass. UPC.State.ActionsBlocked by default; empty turns it off.
Action SpeedPlayback speed of the character's moves (1 as authored, 0.5 half); montages, delays and windows scale together, so a slower enemy keeps the same combo rules.
A character on any move carries UPC.State.ActionRunning, unbroken across a chain; block an ability on it to keep it out of combos.

Add logic to a node: hooks

A hook rides one node's lifetime. Add it to the node's Hooks list; each run gets its own copy.
HookDoes
Locomotion ModifierScales walk speed, acceleration and turn rate while the node runs: 1 no change, 0 none.
Cancel On MovementCuts the node when the character moves, to walk out of a recovery. Needs Can be Cancelled.
Drain VitalDrains a vital each second the node runs. At zero, End Behavior finishes the node (default), cancels it or does nothing.

Drive a graph from Blueprint or AI

NodeDoes
Process Action InputSends one input tag and moment, as a button does; an AI attacks this way. Returns Entered, Buffered, Dropped, Blocked or Forwarded.
Queue Input SequenceFeeds a list of inputs: Chain sends each as the last move starts, Discrete waits for idle.
Set Action Graph, Clear Action GraphSwap the moveset; drawing an item calls them.
Interrupt Action for External AbilityCuts the running move to Root whatever its cancel rules (a hit reaction, a cutscene).
Get Action StateCurrent node, window, time in the node, inputs it offers, any waiting press.
On Action Node Changed, On Action Reset, On Action Cancelled, On Action FailedA node started, the graph returned to Root, an input cut a move, a move could not start.

Debug it

UPC.Debug.Actions 1            // Each character's graph, node, window and waiting press, above its head
Log LogUPCActionGraph Verbose  // The same in the log
Debug Overlay Actions on one character's component limits the overlay to that character. In Play In Editor the running card lights green (Action Graph Editor).
AdvancedPayloads in detail
  • Play Montage: Play Rate multiplies the montage's rate. Section Name picks the starting section (None or a missing name, which the compile reports, plays from the start). No Montage: the move ends at once with a warning.
  • Back Montage, Left Montage, Right Montage replace Montage when the stick pushes that way against the body's facing as the move starts; empty plays Montage. Turn To Input At Start turns the body to the push and plays Montage while rotation follows movement; it needs the character base's Attack Approach component.
  • Stop Distance and Make Room Seconds (Spacing) give an attack its own spacing, for a move whose reach differs from the weapon in hand, such as the demo's shield bash beside the sword (25 cm). Stop Distance wins over a window's, the weapon's and the style's; Make Room Seconds 0 turns the step back off for this move and above 0 turns it on under any style. -1, the default for both, follows the rest (Attack Steering). Both need the character base's Attack Approach component.
  • Hold and Delay open the action window as they start (Open Action Window, on), so an input leaves at once; a Hold with it off waits for a window only a hook can open. A Hold's Applied Tags stay on for the stance, for an anim layer to follow. A Delay of 0 ends at once.
  • Trigger Ability / Event: Send Gameplay Event sends Event Tag with Event Magnitude and Optional Object; Activate Ability By Tag starts abilities carrying any Ability Tags. End Immediately (on) ends the node at once; off, it waits for a triggered ability, a cancel or a transition.
  • Retrigger From Root On Failed Start (Execution, Advanced): a failed start reruns the press once from Root, so a targetless finisher becomes a new combo's first hit.
AdvancedPayloads, conditions and hooks of your own
  • Payload: a Blueprint child of UPCActionPayload overriding Execute joins the picker. Return true to keep the node alive (a montage it plays ends it), false to end it. With no montage, the component's Open Action Window and Close Action Window set the chain window.
  • Condition: a Blueprint child of UPCTransitionCondition overriding Evaluate (and Get Condition Display Name for the router label).
  • Hook: a Blueprint child of UPCActionHook receives Enter Action, Exit Action (with the end reason), Tick Action while Tick is ticked, and the montage's Montage Notify events. Finish Node (tick Finishes Node) ends its node; Cancel Node cuts it, honoring Can be Cancelled and Cancel Window Start; the graph picks the next node. A magnifier beside a Blueprint hook selects it in the Content Browser.
AdvancedWhat happens to one input
An input enters at the topThe first stop that acts on it ends the walk
1
Global Block Tags
Action Graph component
While any of these tags is on the character, a press drops and is not held for later. Releases still pass, so a held move can end.
2
Pick the transition
the current node's transitions
Transitions for this input and this moment compete when their Required Tags, Blocked Tags and Conditions pass: highest Priority, then most conditions, then first in the list.
3
Interrupt
the transition's Timing
A winning transition set to Interrupt fires at once when the running move is past its Cancel Window Start; the action window and the cancel rules play no part. A press made earlier goes on to the stops below.
4
Cancel
the node's Cancellation settings
A move marked Can be Cancelled, past its Cancel Window Start, that this input is allowed to cancel, is cut when it has no transition for the input or its window is closed. On Action Cancelled fires and the input runs again from Root.
5
Chain
Root, or an open action window
At Root, or while the running move's action window is open, the winning transition is taken.
6
Wait
Default Input Buffer Mode, or the node's Input Buffer Override
Otherwise the press waits in a one-press buffer, when this node or Root has a transition for it. It runs against this node when the window opens, or from Root when the move ends; a press only Root answers drops if the window opens first. The buffer mode decides which press is kept; anything else drops.
The input that started a move cannot cancel that move, so mashing the attack button cannot cut a swing back to its own start.
  • The buffer rule covers presses; releases wait first come, first served. Ignore suits a move that should not queue the next attack, Accept First a charge. A waiting press that continues the combo counts however old.
  • Only a move that ran to its end and returned to Root grants Late Input Grace (not one cut short or moved on through Action Completed); an input it has no link for starts from Root.
  • Cancel Window Start limits cancels, Cancel On Movement and Interrupt transitions alike.
  • A Global Block Tag present as a move completes sends it to Root, not along Action Completed.
EndMeansWhat follows
CompletedThe montage or payload ended it.A waiting press chains (from Root when only Root answers it), else Action Completed, else Root.
CancelledAn input, hook or outside system cut it.Root, no chain.
RejectedThe server refused a move the player's machine started.The waiting press clears and the character returns to the server's node.
The demo
  • AG_UPC_Sword's light combo chains At Completion: AM_UPC_Sword_Combo carries no action window. AG_UPC_TwoHanded and AG_UPC_Unarmed chain on authored windows.
  • The sword's guard is the held stance above, in nodes named Guard Raise, Guard Hold and Guard Lower.
  • The demo graphs' hops pick among AM_UPC_Hop_F, AM_UPC_Hop_B, AM_UPC_Hop_L and AM_UPC_Hop_R with direction montages.
  • BP_UPC_Enemy_Weak runs at Action Speed 0.5.
MultiplayerWhat runs where
The server runs every character's graph; other machines play what it publishes. Each node is a predicted ability: the player's machine starts it at the press and the server confirms once the node is reachable, no Global Block Tag is on, gates are open, costs affordable and the payload may start. A refusal puts the player back on the server's node.
  • For a remote player the server also refuses a chain sooner than the payload's earliest action window by more than Dwell Grace Base Seconds (0.1, advanced Multiplayer group) plus the round trip. A cut the node's rules forbid locks that player's moves until the cut node's window would have opened.
  • A press after a draw, before the server has sent that weapon's moves, goes to the server and plays about 1.5 round trips later (Forwarded); Max Server Inputs Per Second (20) caps these per player.
  • The server keeps a finished move for the late grace plus at least half a second, accepting a late press the player's machine played at once.
  • Action Speed does not replicate and has no setter; set it on the Blueprint or placed character.
  • From server code, cut with Interrupt Action for External Ability; a cancel made straight on the node's ability reads as a player skipping a recovery.
  • Hooks run on the server and owning machine: gameplay on Has Authority, cosmetics on Is Locally Controlled.
  • On the owner a node's Applied Tags can outlast it by about a round trip. A PlayerState ability system takes Mixed replication, an AI pawn's Full.
  • UPC.Debug.Net.RejectNextActivation 1 (editor builds) makes the server refuse the next move once; the overlay names the server's node while the two disagree.
C++C++
  • UUPCActionGraphAsset holds the compiled ActionNodes; index 0 is Root. The editor's compile writes FUPCActionNode::Transitions; a graph built in code calls ApplyGateEdgeTags() once its gates and transitions are in place.
  • UUPCActionGraphComponent::ProcessActionInput(FGameplayTag, EUPCTransitionTrigger) returns an FUPCActionResult; an overload takes the owned tags and an FUPCInputContext for directional conditions. StartInputSequence is Queue Input Sequence.
  • A payload subclasses UUPCActionPayload and overrides virtual bool Execute(UUPCPayloadHostAbility& Host), optionally GetEarliestChainTime and GetCompletionTime (both take Action Speed), CanStart and CollectPreloadAssets. The host's PlayMontage and PlayDelay apply Action Speed.
  • A hook subclasses UUPCActionHook and overrides EnterAction, ExitAction(EUPCActionEndReason), TickAction and OnMontageNotify*; FinishesNode() returns true for one that ends its node.
  • A condition subclasses UUPCTransitionCondition and overrides Evaluate_Implementation(const FUPCTransitionEvalContext&) and GetConditionDisplayName_Implementation. Characters share one condition object, so it holds no state.
  • OnActionNodeChangedNative, OnActionFailedNative and OnActionEndedNative(NodeIndex, Reason) are the native events. In editor builds, FUPCDelegates::OnActionGraphActivated fires when a component receives a graph.
AdvancedTroubleshooting
Nothing happens when I press the button
  • No ability system. The Output Log says the character has a graph and no Ability System Component. Add one.
  • The input does not reach the graph. The item's Input Mappings must send the tag the transition listens for (Input).
  • A Global Block Tag is on the character, such as UPC.State.ActionsBlocked from a stagger or interaction.
  • The buffer dropped it. A node set to Ignore drops each press made before its window.
  • An edit made during play. Press Compile, or save the graph.