Hit Reactions

Documentation Unreal Engine Player Combat Hit Reactions Gameplay Ability System

Hit reactions make a struck character answer the blow: an event sent as the hit lands and an ability that answers it, with poise deciding which hit breaks through and hyper armor carrying a heavy swing on.


Set it up

5 minutes
  1. 1

    Create the reaction ability

    A reaction is a gameplay ability that a hit effect starts by sending it an event. It stops the attack the character is making, holds its next action back, and moves the body only through the montage it plays. The bone flinch is Physical Reactions, a separate system that can play on the same hit. Create a Blueprint class whose parent is Gameplay Ability, named GA_MyHitReact, and set its Class Defaults. It is Server Initiated because the event goes out on the server:
    GA_MyHitReact
    ▾Class Defaults
    Net Execution PolicyLocal Predicted
    Activation Owned Tags 
    Ability Triggers0 Array elements
    Activation Owned Tags are held while the ability runs, so UPC.State.ActionsBlocked refuses every press until it ends. Leave Instancing Policy on Instanced Per Execution: each hit runs its own copy.
  2. 2

    Cut the attack, wait, end

    In its event graph, cut the attack the character is making with Interrupt Action for External Ability on its UPC Action Graph, which ends the running move whatever its cancel rules say and does nothing while idle. Then wait 0.4 seconds (a float variable Hold Seconds) and end.
    GA_MyHitReact · Event Graph
    Event ActivateAbility
    Get Avatar Actor from Actor Info
    Return Value
    Get Component by Class
    Target
    Component ClassUPC Action Graph
    Return Value
    Interrupt Action for External Ability
    Target is UPC Action Graph
    Target
    Hold Seconds
    Wait Delay
    Task
    Time
    On Finish
    End Ability
    Target is Gameplay Ability
    Targetself
    For a flinch animation, use Play Montage and Wait in place of Wait Delay, and end the ability from its On Completed, On Interrupted and On Cancelled pins: the character starts nothing new until the flinch ends. An ability that ends first stops the montage (Stop when Ability Ends, on by default).
  3. 3

    Grant it to the enemy

    Use an enemy of your own built on the UPC Character Base; the demo enemies already answer UPC.Event.Reaction. Give BP_MyEnemy a Starting Ability Set AbilitySet_MyEnemy (right-click in the Content Browser, UPC, Actions, Ability Set; rows in Input) with a row of Granted Gameplay Abilities holding GA_MyHitReact and Input Tag empty, since an event starts it, not a key.
  4. 4

    Send the event when a hit lands

    Open the Defense Rule Set the enemy's UPC Defense component names as its Defense Set, or make one (UPC, Damage and Defense, Defense Rule Set) and set it there (Defense). Add a UPC Send Gameplay Event to Outcome Effects: Event Tag UPC.Event.Reaction, only Target under Affected Sides, Require Damage Applied ticked, and UPC.DamageResult.Blocked and UPC.DamageResult.Parried in Suppress on Result Tags.
    Details
    DefenseRuleSet_MyEnemy
    UPC
    Defense
    Responses
    0 Array elements
    Outcome Effects
    1 Array element
    Index [ 0 ]
    UPC Send Gameplay Event
    Event Tag
    UPC.Event.Reaction
    Suppress on Result Tags
    2 Gameplay Tags
    UPC.DamageResult.Blocked
    UPC.DamageResult.Parried
    Require Any Result Tags
    0 Gameplay Tags
    Require Damage Applied
    Run on Damageable Hits
    Run on Inert Hits
    Run on Scenery Hits
    Affected Sides
    Target
    A hit that drains health sends UPC.Event.Reaction to the struck character; a blocked or parried one sends nothing.
  5. 5

    Press Play and hit the enemy mid-swing

    Its attack stops, and for 0.4 seconds it starts nothing new; a blow it blocks or parries leaves it swinging. A second hit during the hold starts another reaction. To flinch only when poise breaks, as the demo does, add Poise.

Send the event

Author UPC Send Gameplay Event in one place per reaction, since each place runs:
Authored onSuits
The defender's Outcome EffectsA reaction of the character's, whatever struck it, such as the demo's flinch. Runs after the pools drain.
The attack's damage config Hit EffectsA reaction of the blow's, such as a launcher.
On Damage Taken on the characterA reaction needing Blueprint logic. It runs on blocked and parried hits too, so check the Result.
A new entry's Affected Sides starts on Attacker, so tick Target for the struck character. An ability triggered on a parent Event Tag also answers its children: one on UPC.Event.Reaction answers UPC.Event.Reaction.Stagger. The effect's outcome gates (Damage and Hit Effects) pick which hits send it; a character with no ability system receives nothing.

Poise: flinch only when it breaks

Poise is a small pool every hit drains: the character flinches on the hit that empties it and the pool refills, so light weapons need a few hits for a flinch and heavy ones one.
  1. The pool. Add a UPC Vitals row with Vital Tag UPC.Vital.Poise and Depleted Result Tag UPC.DamageResult.PoiseBroken, which the emptying hit reports. Regen Delay Seconds is the pause; a Regen Rate Per Second equal to Max Value refills it in a second.
  2. The damage. Add a UPC.Vital.Poise row to each attack's Additional Vital Damage: how hard it staggers.
  3. The flinch. On the reaction's UPC Send Gameplay Event, put UPC.DamageResult.PoiseBroken in Require Any Result Tags and untick Require Damage Applied, so a break flinches even with no health damage.
  4. The refill. Beside it, add a UPC Refill Vital with Vital Tag UPC.Vital.Poise and UPC.DamageResult.PoiseBroken in Require Any Result Tags. It reaches the struck character by default (Affected Sides on Target) and fills the pool on the break even when the flinch is refused.
With the demo enemy's 40 poise and a 25-poise sword hit: the first hit leaves 15; the second empties the pool, reports UPC.DamageResult.PoiseBroken, flinches the enemy and refills it to 40.
UPC Vitals
▾Vitals, Poise row
Vital TagNone
Max Value100
Regen Rate Per Second0
Regen Delay Seconds0
Depleted Result TagNone
The demo enemy's row.

Hyper armor

A swing that should carry through light hits holds UPC.State.HyperArmor, from a UPC State Tag Window over its frames (Animation Integration). With poise, make it a poise bonus: add this response to the defender's rule set, below its guards.
DefenseRuleSet_MyEnemy
▾Responses > Index [ 0 ] (UPC Scale Damage)
Required Defender Tags 
Damage Multiplier 
Vital Damage Multipliers 
Continue After Claim
Health passes at full value; poise takes half.
Light hits drain half their poise and the swing goes on; a heavy hit, or a worn-down pool, still breaks it. A 40-poise enemy takes 12.5 from a 25-poise sword hit under hyper armor, so it breaks on the fourth hit instead of the second.
Without poise, list the tag in the reaction's Activation Blocked Tags: no hit stops the swing, though health drains and the physical reaction plays.

Answer the attacker: a parry recoil

On the attack's damage config, or the parrying set's Outcome Effects, add a UPC Send Gameplay Event with Affected Sides on Attacker, UPC.DamageResult.Parried in Require Any Result Tags, and the tag a recoil ability triggers on. Make that ability Server Initiated too: a Local Predicted one never starts for a player who swung.

Debug it

ShowDebug AbilitySystem lists a character's abilities and tags (is the reaction granted, is hyper armor or UPC.State.ActionsBlocked on). LogUPCDamage names an effect with no Event Tag.
AdvancedWhat the event carries
  • Instigator is the character that swung, Target the one struck.
  • Event Magnitude is the health damage that landed, 0 for a hit draining stance alone.
  • Target Tags are the defender's result tags, such as UPC.DamageResult.Blocked, for one ability to branch on.
  • The hit rides along in the target data (Get Hit Result from Target Data, index 0) and the effect context (GetHitResult). The event carries no blow direction.
  • An attack whose outcome tag sits in the melee trace's Skip Record Tags sends the event on each landing; list the reaction's own state tag in its Activation Blocked Tags to answer the first only.
AlternativeCutting from the ability grant instead
A row in a UPC ability set with Interrupts Action Graph ticked cuts the running move whenever its ability starts, so the reaction needs no Interrupt node. Its Activation Blocked Tags decide first.
The demo
GA_UPC_HitReact is the demo's reaction, granted by AbilitySet_UPC_Enemy and AbilitySet_UPC_Default. Every demo character but the two showcase hit dummies carries a Poise row and points at DefenseRuleSet_UPC_Character, holding the flinch event, the refill and the hyper armor response. DefenseRuleSet_UPC_Sword and DefenseRuleSet_UPC_TwoHanded send UPC.Event.ParryRecoil to a parried attacker, which GA_UPC_ParryRecoil answers.
Hits to break, full pool / under hyper armorPlayer 70Enemy 40Over Shoulder boss 100Soulslike boss 180
Punch, 204 / 72 / 45 / 109 / 18
Sword, 253 / 62 / 44 / 88 / 15
Two-handed light swing, 303 / 52 / 34 / 76 / 12
Sword heavy, Counter, shield bash, 602 / 31 / 22 / 43 / 6
Heavy punch, two-handed heavy, 1201 / 21 / 11 / 22 / 3
AM_UPC_Unarmed_Combo, section 5
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
Notifies
UPC State Tag Window, UPC.State.HyperArmor
Trace
UPC Melee Trace Window
The unarmed combo's sixth punch holds hyper armor through its windup and swing; the two-handed Heavy Attack holds it on its move.
MultiplayerWhat runs where
  • The server decides the reaction: a Server Initiated ability starts there and on the struck player's machine about a round trip after the hit, so a press made in between is refused and rolled back.
  • The break, the flinch and the refill are the server's, which reads hyper armor off its own copy of the montage.
C++C++
  • UUPCSendGameplayEventHitEffect (UPCFoundation) builds the event payload; CanPlayAhead returns false.
  • UUPCRefillVitalHitEffect (UPCFoundation) calls the vitals component's FillVital on the authority, skipping a character with no row for the vital.
  • A vital row's DepletedResultTag reaches the hit's ResultTags through UUPCDefenseStatics::ApplyDamageResultToVitals on the emptying hit, before the outcome effects run.
  • UUPCActionGraphComponent::InterruptActionForExternalAbility cuts the running node from outside the graph.
AdvancedTroubleshooting
SymptomFix
Nothing happens on a hitGrant the reaction, match its Trigger Tag to the Event Tag, and tick Target under Affected Sides.
The reaction plays but the swing goes onCall Interrupt Action for External Ability, or grant it with Interrupts Action Graph.