Landing an attack drops HP. But if the enemy just stands there, it is hard to tell the hit connected. In that case, alongside the damage number, build a reaction at the moment of impact .
Their motion dulls for an instant, the screen shakes slightly, and they get pushed back. From the same attack, where you hit and how hard becomes much clearer. Here we add all three to a practice dummy and compare.
What You'll Learn
- What hitstop, screen shake, and knockback each convey
- Structuring the three effects so they fire only on a hit
- Slowing only the target briefly and returning it to normal speed
- Comparing effects one at a time to tune the feel
- Three reactions convey the hit
- Hands-On prep: build a dummy that takes hits
- Screen shake: brief and small
- Knockback: launch away from the attacker
- Hitstop: slow the target for an instant
- Call all three at the moment of impact
- How to tell when it is too much
- When you want to add light, sound, and numbers
- Bonus: Good to Know Up Front
- Summary
Three reactions convey the hit
The sensation returned to a player's input is called game feel . Within that, telling them an attack landed through motion, visuals, and sound is the hit feedback we build here.
| Effect | What it does | What it conveys |
|---|---|---|
| Hitstop | Briefly stops or slows motion at the moment of impact | The sense of the attack biting in |
| Screen shake | Shakes the camera briefly | The strength of the impact |
| Knockback | Pushes or launches the target back | The direction of force and who was hit |
You do not need all three at full strength. A light attack reads with just a small shake. A heavy blow can add a brief hitstop and a larger launch.
What matters is calling them at the moment a hit is confirmed, not the moment the attack button is pressed . Launching things or shaking hard on a whiff removes the cue that tells a hit apart.

Hands-On prep: build a dummy that takes hits
Use a Third Person level where pressing E attacks a dummy in front of you. For the attacking side, prepare the attacker from the health and damage article. It extends a 500 cm line in front of the character and sends 20 damage to what it hits with Apply Damage .
This article builds only the receiving side: a dummy with no HP or death logic, so you can test the effects endlessly. It assumes you can create Blueprint variables and Custom Events, in single player.
- Create a Blueprint Class with "Character" as its parent and name it
BP_HitFeedbackDummy. A Character is an Actor with walking and falling built in. TheLaunch Characterwe use later needs it, so do not choose a plain Actor. - Add a "Static Mesh" component named
Bodyas a child of the Capsule Component, with meshCube, Scale(0.6, 0.6, 1.8), and Location(0, 0, -6). If you cannot find Cube, turn on "Show Engine Content" and chooseEngine/BasicShapes/Cube. - Set the Capsule Component's Radius to
42and Half Height to96. Change the Collision Preset from "Pawn" to "Custom" and set the Visibility response to Block so the attack line hits this capsule. - Set Body's Collision Preset to "NoCollision" with Simulate Physics off. Leave movement and collision to the capsule.
- In Class Defaults, turn Can Be Damaged on and set Auto Possess Player and Auto Possess AI to "Disabled". In Character Movement, turn Run Physics With No Controller on so a dummy without AI still updates movement and falling.
- Compile and place it in the level. Put the capsule's center about 100 cm above the floor and about 300 cm from the player. If an earlier practice box exists, move it out of the attack line.

First walk toward the dummy and press E , confirming the debug line hits it. The attack direction is the character's forward, not the camera's. The dummy need not move at this stage.
All three effects go in BP_HitFeedbackDummy 's Event Graph. At the end we call them together from the hit event.
Screen shake: brief and small
Start with the shake, whose visual change is easiest to see. Camera Shake temporarily adds position and rotation changes to the camera. Here we use a short rotational shake, like a small nod.
Make the shake pattern an asset
- In the Blueprint Class creation screen, open "All Classes", search for
CameraShakeBase, and choose it as the parent. Name itCS_HitFeedback. - In the opened Blueprint's Class Defaults, set "Root Shake Pattern" to "Perlin Noise", one way of generating a shake.
- Set the following values, then compile and save. Expand Root Shake Pattern to find them.
| Setting | Starting value | Meaning |
|---|---|---|
| Single Instance | On | Restarts the same shake instead of stacking on mashing |
| Duration | 0.15 | Total length of the shake, in seconds |
| Blend In Time / Blend Out Time | 0.02 / 0.08 | Time easing the shake in and out |
| Rotation → Pitch → Amplitude | 1.0 | The vertical shake amount |
| Rotation → Pitch → Frequency | 25 | How fine the shake is |
| Rotation → Yaw / Roll → Amplitude | Both 0 | No horizontal swing or tilt |
| Location → X / Y / Z → Amplitude | All 0 | Do not shake the camera position |
| FOV → Amplitude | 0 | Do not change the field of view |
Leave Rotation's Amplitude Multiplier and Frequency Multiplier at 1 . Amplitude is the shake amount and Frequency is how fine it is. Changing only the amount at first makes differences easy to grasp.

Send the shake from the dummy to the camera
Create an argument-less Custom Event PlayLocalHitShake on BP_HitFeedbackDummy . A Custom Event here is an entry point you can call by name later.
Wire its white exec pin to Start Camera Shake with Shake Class CS_HitFeedback , Scale 0.5 , and Play Space "Camera Local". Scale is how many times over to apply this one shake.
Connect Get Player Camera Manager 's Return Value to Target with Player Index 0 . The Player Camera Manager manages the camera the player sees. Rather than targeting the dummy itself, we tell that manager to "shake the screen".

As an interim check, place Event AnyDamage in the Event Graph and wire white exec to the PlayLocalHitShake call. Play, attack the dummy, and a small shake on impact means success. Disconnect that wire afterwards; we replace it with the three-effect call at the end.
Knockback: launch away from the attacker
Next we push the dummy. Launch Character gives velocity to a Character. That velocity is used on the next Character Movement update and puts the Character into Falling, the airborne state.
Rather than sliding along the ground, we make it rise slightly and fly back. First, build the launch direction.
Build the direction from the position difference
If the attacker is to the dummy's left, launch right; if to the right, launch left. So we build a vector from the attacker to the dummy with "dummy position − attacker position" . A vector here is an arrow representing "which way, and how far".

- Create a Custom Event
ApplyHitKnockbackonBP_HitFeedbackDummywith an inputSourceActortyped Actor Object Reference . It receives the attacker. - Place two
Get Actor Locationnodes, one with Target Self and one connected to the SourceActor blue output pin on the Custom Event. - In a Vector subtraction, connect Self's position to the upper A and SourceActor's position to the lower B. Reversing them would pull the dummy toward the attacker.
- Connect the subtraction result to
Normalize 2D (Vector)'s A. It drops the vertical difference and normalizes the horizontal length to 1, so launch strength does not vary with distance. - Multiply the result by Float
600and add Vector(0, 0, 150). That gives 600 horizontally and 150 upward. The unit is cm per second, not a distance of 600 cm .

With the direction decided, add strength to it.

The two diagrams connect Normalize 2D (Vector) 's Return Value to the Vector input of the Vector-times-Float multiply.
Pass the velocity to the Character
Wire ApplyHitKnockback 's white line to Launch Character with Target Self and Launch Velocity from the vector computed above. Turn on both "XY Override" and "Z Override". Override means replacing the current movement speed with the specified velocity rather than adding to it.

For an interim check, wire Event AnyDamage 's white line to the ApplyHitKnockback call and Damage Causer to SourceActor. Damage Causer is the attacker passed as Self in the attacker's Apply Damage. In this practice attack, the player goes there.
Play and attack the dummy; rising slightly and flying away from the player means success. Hit from the other side and confirm the direction flips. Disconnect this temporary wiring afterwards.
Hitstop: slow the target for an instant
Finally, slow the dummy only at the moment of impact. Stretching the start of the push-back briefly shows the moment of contact. Rather than a full stop, we run the dummy at 0.05 times normal speed for 0.07 seconds .
Change the target's time multiplier, not the world's
Time Dilation is the multiplier applied to how time progresses. 1 is normal and 0.5 is half speed. UE has a Global one changing the world and a Custom one per Actor.
| Setting | Main use | Here? |
|---|---|---|
| Global Time Dilation | Slowing the whole world together | Stays at 1 |
| Custom Time Dilation | Slowing a specific Actor's Tick, Character movement, and more | Set the dummy to 0.05 |
Tick is the update logic that runs repeatedly as the game progresses. Custom Time Dilation changes the elapsed time passed to that Actor. It does not put sounds, timers, and physics related to the Actor all on the same multiplier. Here we apply it to a dummy that moves via Character Movement.

For restoring, use Set Timer by Event . It is a reservation that calls a connected event once the specified time arrives . Execution continues after reserving, so the screen shake and knockback can start on the same hit.
That timer is not slowed by the dummy's Custom Time Dilation. It is affected by Global Time Dilation and by pausing, though. Keep Global at 1 and test unpaused. This does not mean "Timers ignore time changes".
Remember the original speed and reserve the restore
Create these variables on BP_HitFeedbackDummy .
| Variable | Type | Default | Role |
|---|---|---|---|
SavedTimeDilation | Float | 1 | Remembers the multiplier before slowing |
bHitStopActive | Boolean | false | Remembers whether a hitstop is already running |
Then create two argument-less Custom Events named StartLocalHitStop and EndLocalHitStop . Wire the Start side in this order.
StartLocalHitStop→BranchwithbHitStopActiveinto Condition. Leave True unconnected so a running hitstop does not start a new one.- False →
Set SavedTimeDilation, with Self'sGet Custom Time Dilationas the value, saving the pre-change multiplier. - →
Set bHitStopActiveto true. - →
Set Custom Time Dilationwith Target Self and value0.05. - →
Set Timer by Eventwith Time0.07and Looping off. ConnectEndLocalHitStop's red delegate output to the red Event input. A delegate is the pin passing "the event to call later" to the timer.

Once saved, actually slow it and reserve the restore.

The images split one graph into a first and second half. Connect the first half's Set bHitStopActive exec output to the second half's Set Custom Time Dilation exec input. EndLocalHitStop is the same event used in the restore logic next.
When the time arrives, return to the saved speed
Wire EndLocalHitStop 's white line to Set Custom Time Dilation with Target Self and SavedTimeDilation as the value. Then set Set bHitStopActive to false so the next hitstop can be accepted.

We do not write a fixed 1 here so it also restores correctly when the speed was already something else. And saving repeatedly during a hitstop would overwrite the original value with 0.05 . The first Branch prevents that.
Giving each dummy its own restore logic matters too. Relying on the attacker's "last target hit" variable can leave an earlier dummy unrestored once you hit another. This structure has each dummy remember and restore its own multiplier.
Call all three at the moment of impact
With the three effects built, wire them from BP_HitFeedbackDummy 's Event AnyDamage .
Event AnyDamage→BranchwithDamage > 0into Condition.- True → the exec-pin
Is Validwith Damage Causer into Input Object. That checks whether the Actor passed as the attacker is usable. - Is Valid →
Sequence. The invalid case and the first Branch's False can stay unconnected. - Wire Sequence's Then 0 →
StartLocalHitStop, Then 1 →PlayLocalHitShake, and Then 2 → theApplyHitKnockbackcall. Add Then 2 with "Add pin". - Connect Event AnyDamage's Damage Causer to
ApplyHitKnockback's SourceActor. Target on all three calls is Self.

Also confirm the attacker is valid.

Once both checks pass, call the three effects together.

Wire the three diagrams as Branch's True → Is Valid's exec input, then Is Valid's success side → Sequence's exec input. The blue Damage Causer wire is used both for the Is Valid check and for passing SourceActor.
Sequence sends white exec through several outputs in order. After Then 0 reserves the timer, it continues to Then 1 and Then 2 without waiting for expiry. So the shake and knockback also start on this hit.
Play and attack, and the screen shakes slightly while the dummy moves slowly at first and then flies back. If the hitstop is hard to notice, temporarily raise the Timer's Time to 0.3 to see the boundary between slow and normal motion. Set it back to 0.07 afterwards.
This dummy is for practice, so it plays effects for any positive damage. Once real enemies have invincibility frames or guarding, move these three calls after the logic that actually accepted the damage . Event AnyDamage arriving does not guarantee HP drops.
How to tell when it is too much
Once it is done, before strengthening everything at once, compare by removing one effect at a time. Stop Play, disconnect one white wire from the Sequence to an effect, and play again to see that effect's role. Restore the connections after comparing.
| What to compare | What to watch | Where to tune |
|---|---|---|
| Hitstop on versus off | Whether hits read better, or the attack flow feels heavy | Timer's Time from 0.07 → 0.04 |
| Shake on versus off | Whether impact carries, or you lose track of the target | Start Camera Shake's Scale from 0.5 → 0.25 |
| Knockback on versus off | Whether you can tell who was hit, or your follow-up cannot reach | The horizontal multiplier from 600 → 300 |
Stronger is not always better. In a combo, sending the target too far makes the second hit hard to land. Keeping normal attacks light and strengthening only the finisher creates contrast without fighting the controls.

Duplicate the dummy, attack two in a row, and confirm both return to normal speed. This structure does not extend the time on an additional hit during a hitstop. It restores 0.07 seconds after the first hit, while the shake and knockback still fire on additional hits.
When you want to add light, sound, and numbers
With three reactions working, you can add more information. Deciding what you want to convey before choosing keeps things from getting merely noisy.
| Reaction to add | What it conveys | How to build it |
|---|---|---|
| Flash the target briefly | Which target was hit | Changing color with a Material Instance |
| Play a hit sound | Hits read even when your eyes are elsewhere | Playing sound effects |
| Emit sparks | Where it hit | Hit effects with Niagara |
| Show damage numbers | How much it did | Floating damage numbers |
Add one and try the same attack a few times. You do not need sound, light, and numbers all at once; it is enough if what you want to convey reads.

Bonus: Good to Know Up Front
- Anim Notify and the hit are separate. A Notify announces where in the attack animation the check happens. At that timing you run a Trace or Overlap, and when the target accepts damage, you call these effects.
- Keep the Timer's Time positive. At
0or below the timer is cleared. Setting Time to 0 to disable hitstop would lower the multiplier with no restore reserved. To compare, disconnect the call's white wire instead. - If other logic also changes Custom Time Dilation, adjust for it. If a slow spell expires during a hitstop, for instance, restoring the old multiplier alone leaves the state inconsistent. In this hands-on, hitstop is the only thing rewriting this dummy's multiplier.
- Launch Character also changes the movement state. When combining it with AI move commands or ground sliding, also handle things like stopping the chase while launched. Physics-simulating boxes need a different mechanism.
- Screen shake is a per-player effect. Player Index 0 here is the first local player in single player. In multiplayer, separate the side processing damage from the side shaking the screen. Letting players lower or disable shake intensity in settings makes tuning easier.
Official references: Camera Shakes, Start Camera Shake, Launch Character, Gameplay Timers. The hands-on is a Blueprint example based on those specifications and has not been verified on UE hardware.
Summary
Attack feel is built from reactions telling the player a hit landed. Here a brief slowdown showed the moment of impact, a screen shake added force, and knockback expressed the direction.
Confirm each on a practice dummy first, then gather them into the hit logic. Comparing against the version with an effect removed, not only adding effects, reveals the strength your game actually needs.