Paired Actions

Documentation Unreal Engine Player Combat Paired Actions

A paired action is one move two or more characters play together, such as an execution, a counter or a grab: each fills a role with its own montage, and all line up around one spot on the ground.


Set it up

10 minutes
  1. 1

    Create a Paired Action

    Create a Paired Action named Paired_MyExecution and double-click it to open the pairing editor.
    Content Browser
    ▸ Content
    Right-click in the Content Browser, UPC, Paired, Paired Action.
  2. 2

    Add two roles

    In Roles, click Add Role twice and name them Attacker and Victim (Pairing Editor covers the star and renaming). The anchor is the spot on the ground the roles line up around. A placed spot's own location and facing are the anchor (The anchor). In Details, set the Attacker's Montage to AM_UPC_Unarmed_Execute_Attacker_B and the Victim's to AM_UPC_Unarmed_Execute_Victim_B.
    Roles
    + Add Role
    Attacker★×
    Skeletal Mesh ▾None
    Victim×
    Skeletal Mesh ▾None
    The first role added becomes the anchor and carries the star. F2 or a right-click renames a role; the right-click menu also holds Set as Anchor and Delete.
  3. 3

    Line them up

    Click Derive Offsets: the Victim's ring moves to where the montages place it. If it stays, drag the Victim's stand-in until the poses meet. Save.
  4. 4

    Put it in the level

    Make a Blueprint Actor BP_ExecutionSpot with UPC Paired Action Spot (Paired Action Paired_MyExecution) and UPC Paired Action Interactable (Instigator Role Attacker). Place it, drop the demo's BP_UPC_PairedDummy (Showcase/Paired) on the Victim's ring, and add a Placed Role Actors entry Victim naming it.
    Components
    + Add
    BP_ExecutionSpot (Self)
    UPC Paired Action Spot
    Add
    UPC Paired Action Interactable
    Add
    What plays and where, and a prompt to join it.
    Details
    UPC Paired Action Interactable
    UPC
    Paired Action
    Spot Component Tag
    None
    Instigator Role
    Attacker
    Placed Role Actors
    1 Map element
    Victim
    BP_UPC_PairedDummy
    Advanced
    Cancel Active on Conflict
    Its own option row, Play Paired Action, ships filled in. Keep its Option Id and leave its Payload empty.
  5. 5

    Press Play

    Stand on the Attacker's ring and press E at Take Part as Attacker: the dummy glides onto its ring and the two play the execution.

Ways to play it

Every character taking part, a prop filling a role included, needs an ability system component and fills one role.
FromUsePicks the characters
A spot in the levelUPC Paired Action Spot and UPC Paired Action InteractableWhoever presses Interact, plus actors you name.
A moveThe Play Paired Action payload on an action graph nodeA search as the node runs.
A button of its ownA Blueprint child of UPCPairedActionTriggerAbilityA search on the press.
BlueprintTry Run Paired Action and its siblings, or Play Paired ActionA search, or the characters you hand it.

In the level

Its rings show in the editor, and in play with Draw in Game. The interactable gives Instigator Role to whoever presses Interact and the other roles to Placed Role Actors, or Set Role Actor (server, on a replicating actor) for a spawned character. Edit its Play Paired Action row's prompt and button, keeping the Option Id and empty payload. On Prepare Play fires on the server before the action starts, to hand over a weapon the action shows.

An execution on a stunned enemy

  1. Duplicate Paired_MyExecution as Paired_MyStunExecution and select Victim:
    • Required Actor Tags UPC.State.Staggered, which the demo's stun holds, so only a stunned enemy fits.
    • Tags During Action, add UPC.State.Intangible, so other swings pass through the victim.
    • Tick Stand Down Actions on Join: the enemy stops what it was doing the moment it joins.
  2. On the Action tab, set Release Rule to When All Finish: the victim stays in the action, untouchable, until the Attacker's part ends too.
  3. In the player's action graph, add a node with the Play Paired Action payload, Paired Action Paired_MyStunExecution, Owner Role Id Attacker.
  4. Wire Root to it on UPC.Input.Execute (Action Graph).
The demo's sword and unarmed items carry IA_UPC_Execute. An enemy of your own needs Pawn collision and an enabled UPC Targetable (Who it picks), and must hold UPC.State.Staggered while stunned.
Details
Finisher
Execution
Payload
Play Paired Action
Source
Paired Action
Paired Action
Paired_MyStunExecution
Owner Role Id
Attacker
Target Teams
Enemies Only
Primary Picker
None
Gather Radius
400
Gather Arc Degrees
180
Play Rate Override
0.0
Cancel Active on Conflict
Source Paired Action plays the one move named here with whoever fits it. Source Paired Action Sets swaps these rows for a Paired Action Sets list.
On the press, the node looks within Gather Radius (400 cm) and Gather Arc Degrees (180) for an enemy (Target Teams, Enemies Only) that fits the Victim role (Who it picks) and stands within the action's Max Slot Distance (200 cm by default, 0 accepts any) of its slot; an enemy inside the radius but farther from its slot is rejected. Finding none, it refuses and Action Failed runs. The node ends as the paired action starts. The action itself then keeps both characters until each role is released (Release Rule).

A counter: sets and the Paired Action Available condition

A counter answers an enemy's swing: Guard pressed while a counterable blow comes in plays a paired move, and a guard otherwise. A Paired Action Set holds the moves, one row per move with the situation it answers.
  1. The move. Duplicate the demo's Paired_UPC_Unarmed_Counter_A (Demo/Weapons/Unarmed/Animations) as Paired_MyCounter. Its roles are Defender, the player, and Attacker, the enemy whose swing it catches. The demo's Attacker role ticks Sync with Current, so the move takes over the swing already playing; a copy keeps it (the Sync with Current drawer below covers your own).
  2. The set. Create PairedActionSet_MyCounters and add a row: Action Paired_MyCounter, Owner Role Id Defender, Required Target Tags UPC.Attack.Counterable, Priority 10. A telegraph window holds an attack's tags on the attacker as it winds up, so the row answers counterable blows only; the demo's Freeflow punches carry the tag (Patterns).
  3. The button. Wire Guard out of idle twice:
TransitionPriorityConditionLeads to
FirstHigherPaired Action Available, naming PairedActionSet_MyCountersA node with the Play Paired Action payload: Source Paired Action Sets, the same set
SecondLowerNoneThe guard node
Content Browser
▸ Content
Right-click in the Content Browser, UPC, Paired, Paired Action Set.
Details
PairedActionSet_MyCounters
Paired Actions
Options
1 Array element
Index [0]
Action
Paired_MyCounter
Owner Role Id
Defender
Required Target Tags
1 Gameplay Tag
UPC.Attack.Counterable
Priority
10
One row: the move and the situation it answers. The row's other settings keep their defaults.
AdvancedSync with Current
The demo counter ticks Sync with Current on its Attacker role, so the paired move takes over the swing already playing. For your own, tick it on the enemy's role and put a UPC Paired Sync Marker named as the role's Sync Marker (Sync) on the swing's caught frame and the matching frame of the paired montage. Pressed late, the paired montages run up to 4 times faster until the frames meet; pressed early, the action waits while the other roles glide in. A swing with no marker uses its next melee trace window or its telegraph countdown.
  • One role may sync, joining no later than its marker. Set its montage Blend In to 0 (validation's Fix does it), since the handoff is a cut.
  • A marker the paired montage lacks plays the action unaligned, with one warning.
AdvancedWhen several rows fit
  1. The highest Priority wins; a lower row plays only when nothing above it fits.
  2. Among rows of that priority, the best fit wins: the row whose farthest character stands closest to its slot (where its Offset Location and Offset Rotation put it, under Roles). A row whose cast stands beyond the action's Max Slot Distance (200 cm) does not fit at all.
  3. Rows within Fit Epsilon (25 cm) of that best fit count as equal, and Weight draws among them. A Fit Epsilon of 0 plays the best fit with no draw.
Say rows A (Weight 1) and B (Weight 3) share Priority 10. At 60 cm and 75 cm from their slots both sit within 25 cm of the best, so B plays three times in four; at 60 cm and 120 cm, A always plays. A Priority 20 row that fits beats both.
AdvancedCheck a set covers every attack
Set Coverage Root on the set to a root of attack tags, such as UPC.Attack.Counterable: Coverage under it lists each tag beneath that root no row answers, a counter nobody wrote. Editor only; clear it to stop checking.

One action, a different animation for each enemy type

Put a tag of your own, such as Enemy.Type.Heavy, in the heavy enemy's Character Tags. In the set, add a row above the generic one with a higher Priority, Required Target Tags Enemy.Type.Heavy and that enemy's own Action. The generic row, requiring none, stays last for every other enemy.

From a button of its own

Make a Blueprint child of UPCPairedActionTriggerAbility, fill Actions with your sets, and grant it on an Input Tag such as UPC.Input.Execute. A press with nothing to play fails with UPC.Ability.Fail.NoPairedAction, which a failed-activation listener can answer with a guard. The ability ends with the paired action.

From Blueprint

NodeDoes
Try Run Paired ActionPlays one move with whoever fits; Debug draws the search for two seconds.
Try Run Paired Action from Set, from Set ArrayPlays the best fitting row of the sets.
Find Paired Action, Play Paired Action PickFinds a move and cast without playing, for a prompt; then plays it.
Can Run Any Paired ActionWhether anything in the sets could play now.
Play Paired Action, at AnchorPlays with the characters you hand it, at Anchor around a spot you choose, with a pin per stage.
Get Paired Action Slots at Anchor, for BindingsWhere each role would stand.
Off the server, play nodes report Not Authority or fire On Failed.

Who it picks

A search looks around the character for bodies to fill the other roles. A body counts when:
  • its collision is a Pawn object and it carries an enabled UPC Targetable;
  • it stands inside the search's radius and arc, on the side Target Teams allows;
  • its tags fit a role, and it is in no other paired action.
Required roles fill first, then the role the fewest bodies could take; each role takes the body nearest its slot. With a Victim any enemy fits and a Heavy only an Enemy.Type.Heavy enemy fits, the Heavy fills first, so the tagged enemy is not used up as the Victim. A Primary Picker on a row or node picks the main body another way:
PickerPicks
Current TargetThe attack's target, else the lock, else a fresh pick; Repick at Press picks fresh, for a vault the stick aims. Needs UPC Targeting; for a remote player it is the target that player last reported to the server, which exists only when a Target State or Target Distance condition sits on the transition or the targeting config selects continuously.
Proximity ScanThe nearest inside Radius (300 cm) and Max Angle Degrees; 180 includes behind.
Soonest ImpactThe body whose blow lands first; Max Seconds to Impact at 0.6 keeps a counter to swings on their way (0, the default, takes any).
ScoredThe best by a Targeting Config's score policies, the character's own when empty.
Details
Finisher
Paired Action
Primary Picker
Soonest Impact
Min Targets
1
Radius
300
Max Angle Degrees
90
Required Target Tags
0 Gameplay Tags
Max Seconds to Impact
0
Max Targets
1
The body whose blow lands first, for a counter. Set Max Seconds to Impact to 0.6 to keep it to swings already on their way; 0 accepts any wait.
Target Role Id is the role the pick fills (None: the first it may fill), and a pick that fails the row's tags, team or rules refuses the row. As a transition condition in the action graph, a picker passes once it finds Min Targets.

Roles

Attacker (anchor)Victim
At Role, with the Attacker as the anchor: the attacker holds its ground and the victim glides onto the ring in front of it, turned to face it.
Details
Victim
Role: Victim
Offset Location
110.0
0.0
0.0
Offset Rotation
0.0
0.0
180.0
Required
Required Actor Tags
1 Gameplay Tag
UPC.State.Staggered
Blocked Actor Tags
0 Gameplay Tags
Role Start Seconds
0
Role End Seconds
0
Travel Mode
Data Driven
Approach Duration Seconds
0.4
Approach Speed Limit
Unlimited
Tags During Action
3 Gameplay Tags
UPC.State.ActionsBlocked
UPC.State.EquipmentBlocked
UPC.State.Intangible
Stand Down Actions on Join
Cancel Abilities on Join
0 Gameplay Tags
Hooks
0 Array elements
Animation
Montage
AM_UPC_Unarmed_Execute_Victim_B
Start Section
None
Start Delay Seconds
0
Play from Seconds
0
Play to Seconds
0
Sync with Current
Sync Marker
Sync
Preview Stand-In
Preview Kind
Skeletal Mesh
Preview Mesh
None
Preview Anim Instance Class
None
Preview Items
0 Array elements
Preview Scale
1
Preview ZOffset
0
Preview Mesh Yaw Offset
-90.0
The stun execution's Victim. Select a role in the Roles panel, on the timeline or in the viewport; picking its Animation row on the timeline narrows the panel to Animation.
SettingDoes
Offset Location, Offset RotationThe role's slot around the anchor, ground position and yaw only; drag the stand-in to set it.
RequiredOff, the action plays without it: an optional second victim.
Required Actor Tags, Blocked Actor TagsWho may fill it, such as UPC.State.Staggered or an item's equipment tag.
Tags During ActionHeld during the part: UPC.State.ActionsBlocked and UPC.State.EquipmentBlocked by default; add UPC.State.Intangible so swings pass through a victim.
Stand Down Actions on JoinStops the character's action graph as it joins.
Cancel Abilities on JoinCancels abilities by tag as it joins: a raised guard, a spell.
Travel ModeData Driven (default) glides onto the slot in Approach Duration Seconds (0.4), through characters, not walls; Montage Driven moves by a warp window on Warp Target Name (UPCPairedAction) or a UPC Approach Window; In Place stays.
Approach Speed LimitUnlimited (default) arrives on time; Fixed Speed (600 cm/s) and Character's Max Speed can arrive short.
Every character taking part holds UPC.State.PairedAction. The role's bar on the timeline sets when it is in the action, in seconds from the action's start:
  • Role Start Seconds: when the role joins. Its tags go on, its hooks start and its glide begins. 0 joins at the start.
  • Role End Seconds: when the role is let go. 0 leaves it to the Release Rule. Under On Own End, a montage ending sooner lets it go first.
A Data Driven role's montage that starts inside its glide (Approach Duration Seconds after the role's start) loses its root motion until the glide ends. Start the montage after the glide, or use Montage Driven; the pairing editor's validation reports the overlap.

The anchor

Details
Paired_MyExecution
Paired Action
Timing
Play Rate
1.0
Action Length Seconds
0
Anchor
Anchor Mode
At Role
Anchor Role Id
Attacker
Formation Yaw Offset
0.0
Face Toward Role Id
None
Warp Target Name
UPCPairedAction
Cast
Abort Rule
Cancel All
Release Rule
On Own End
Placement
Max Slot Distance
200
Max Slot Yaw Degrees
0
Require Clear Slots
Designer Tools
Designer Tools
Derive Offsets from Montages
The Action tab: settings for the whole action. A role's own settings live in the Details tab.
SettingDoes
Anchor ModeAt Role: under the Anchor Role Id role's feet, which holds its ground. Centroid: the middle of the cast's feet.
Face Toward Role IdTurns the anchor to a role, lining the cast up between them. None keeps the anchor's facing.
Formation Yaw OffsetTurns the formation around the anchor.
Release RuleOn Own End (default) frees each role as its montage ends; When All Finish holds all until the action ends, so a short victim part stays untouchable.
Abort RuleCancel All (default) ends every role when one ends early; Independent does not.
A play that names its own spot, such as a placed spot, ignores Anchor Mode and Face Toward; the spot's location and facing are the anchor.
AttackerDefender
Centroid: the anchor sits between the two bodies and faces the first role, so both glide to meet in the middle.

Hooks on a role

Clear Space clears room as its role starts: bystanders within Radius (500 cm) on Teams stop attacking, any nearer than Keep Out Distance (300 cm) step back over Retreat Seconds, and each holds Held Tags (UPC.State.ActionsBlocked) until the role ends. Put it on the player's role in a counter. Teams reads from the hook's role: there, Enemies Only holds the enemies.
Details
Defender
Role: Defender
Hooks
1 Array element
Index [ 0 ]
Clear Space
Radius
500
Keep Out Distance
300
Retreat Seconds
0.4
Teams
Enemies Only
Stop Actions
Held Tags
1 Gameplay Tag
UPC.State.ActionsBlocked
Ignored Tags
0 Gameplay Tags
Tick
On the player's role in a counter: other enemies nearby stop attacking, back off and wait until the role's half ends.
Authored Camera Shot, Auto Cinematic View and Camera Layer move the camera of the player in the role (Cameras for paired actions; keying a shot: Pairing Editor).

Listen from your own Blueprint

  • A timeline Notify Listener event calls On Paired Action Event, with its name, numbers and words, on a character that implements UPCPairedActionListener and has an ability system.
  • Is Actor in Paired Action and Is Actor in Any Paired Action answer for a character; Is Paired Action Active, Get Paired Action Role Actor, Get Paired Action Roles and Is Paired Action Role Live for a play node's handle.

Debug it

Console variableShows
UPC.Debug.Paired.Draw 1The anchor, each slot and its facing, at every play.
UPC.Debug.Paired.DrawSelection 1Every search: sphere, arc, each body green or red with the reason.
UPC.Debug.Paired 1Over each character in one: the action, its role, its partners.
Log LogUPCPaired Verbose writes why each row was chosen or refused, and Troubleshooting lists what each refusal means.
AdvancedPlacement and casting rules
  • Placement on the Action tab: Max Slot Distance (200 cm, 0 any) is the farthest a character may stand from its slot; Max Slot Yaw Degrees (0, any) the most it may turn; Require Clear Slots refuses a slot something solid stands on, ignoring the cast. The worst character speaks for the cast.
  • Every play checks role tags and placement, characters handed in directly included.
  • A spot's row shows only while its character may fill Instigator Role, each required role has a character near its slot, and nobody is busy. The interactable also fires On Paired Action Started and Ended on the server, and Evaluate Play asks whether the action could play, its Refusal saying why not.
  • Cancel Active on Conflict lets the asking character leave a running paired action for this one, to chain executions.
  • A hook of your own is a Blueprint UPCPairedActionHook with Enter, Exit and Tick Paired Action (Tick on) and On Montage Notify.
  • A row's Rules add checks: Actor Class, or a Blueprint UPCPairedActionRule overriding Should Allow Candidate or Should Allow Pick. A Blueprint UPCPairedTargetPicker overriding Pick Targets is a picker of your own.
The demo
  • The paired hallway runs six BP_UPC_PairedStation actors, each a spot and an interactable, with BP_UPC_PairedDummy as the partner.
  • PairedActionSet_UPC_Unarmed, PairedActionSet_UPC_UnarmedExecute and PairedActionSet_UPC_SwordExecute hold the demo's counters and executions.
MultiplayerOnly the server starts and ends it
  • Every role, the victim's included, starts from an event the server sends to that character's ability system, and plays on every machine from there.
  • The graph node asking for an execution is predicted, so the press feels immediate; the paired action waits for the server. A press finding nobody on the player's machine takes Action Failed there, and the server confirms that route.
  • A part whose montage is over holds on every machine until the server releases the role; the player's copy ignores a local cancel.
  • The trigger ability runs on the server, which works the choice out again. A spot's row on a client is a hint the server checks again.
  • Find Paired Action reads replicated state, so a prompt matches the press except within about 0.1 s plus half a round trip of a timing edge. The handle and actor queries answer on every machine, a client's a moment behind.
  • A gliding role passes through characters on the server and its own player's machine; on a third player's it can still block.
C++C++
  • UUPCPairedActionSubsystem runs every paired action. PlayPairedAction, CancelPairedAction, ReleaseRole and ReleaseRoleAfter are C++ only; Blueprint ends a role early with a Release Role timeline event.
  • UPCPairedActionStatics::ResolveOptions ranks fitting rows (priority, fit, authored order) without changing the world; ChooseRankedIndex (authority) draws among near ties by weight; CheckPlacement runs the placement checks on a cast you chose.
  • Subclass UUPCPairedTargetPicker (PickTargets_Implementation), UUPCPairedActionRule (ShouldAllowCandidate_Implementation, ShouldAllowPick_Implementation), UUPCPairedActionHook and UUPCPairedActionEvent. Pickers, rules and events are shared by every play, so hold no per-play state; hooks are copied per play.
AdvancedTroubleshooting
RefusalMeans
No OptionsNo sets, or every row off or empty.
Owner TagsThe asking character misses a tag the row or role wants, or holds a blocked one.
No CandidatesNothing targetable nearby.
Target TagsNo body has the tags a row or role wants: a counter while the enemy is not swinging.
Team, Already PairingThe only bodies in reach are allies, or busy elsewhere.
Candidate Rule, Pick RuleA row's rule refused every body, or the cast.
Missing RolesToo few bodies for the required roles.
Too Far, Wrong Facing, Slot BlockedThe asset's placement checks.
Not AuthorityIt ran off the server.
Director RefusedA body stopped being valid before the play.