攻撃を当てるとHPは減る。でも、敵がそのまま立っていると、攻撃が通ったのか少し分かりにくい。そんなときは、ダメージの数字に加えて、当たった瞬間の反応 を作ってみましょう。
相手の動きが一瞬だけ鈍り、画面が小さく揺れ、相手が後ろへ押し出される。同じ攻撃でも、どこに、どれくらい強く当たったのかが伝わりやすくなります。今回は練習用の的に、この3つを足して比べます。
この記事でわかること
- ヒットストップ・画面シェイク・ノックバックが伝えるもの
- 命中したときだけ、3つの演出を呼ぶ組み方
- 相手だけを短く遅くして、元の速さへ戻す方法
- 演出を一つずつ比べ、手応えを調整する方法
3つの反応で、命中を伝える
ゲームの操作に対して返ってくる感触を、ゲームフィール と呼びます。そのうち、攻撃が当たったことを動き・映像・音などで知らせるのが、今回作るヒット時のフィードバックです。
| 演出 | 何をする? | 伝わること |
|---|---|---|
| ヒットストップ | 命中した瞬間、動きをごく短く止める・遅くする | 攻撃が食い込んだ感じ |
| 画面シェイク | カメラを短く揺らす | 衝撃の強さ |
| ノックバック | 相手を押し戻す・吹き飛ばす | 力の向きと、当たった相手 |
全部を強くする必要はありません。軽い攻撃なら小さな揺れだけでも変化が分かります。重い一撃なら、短いヒットストップや大きめの吹き飛びを加える、といった使い分けができます。
大切なのは、攻撃ボタンを押した瞬間ではなく、命中を確かめた瞬間に呼ぶ ことです。空振りでも相手が飛んだり画面が大きく揺れたりすると、命中を見分ける手掛かりが減ってしまいます。

実践の準備:攻撃を受ける的を作る
Third Personのレベルで、E キーを押すと正面の的へ攻撃できる状態を使います。攻撃側は 体力とダメージの記事の「攻撃を当てる側」 を用意してください。キャラクターの正面へ500cmの線を伸ばし、当たったActorへ Apply Damage で20ダメージを送る例です。
この記事では、攻撃を受ける側だけを新しく作ります。HPや死亡処理を持たない、演出を何度でも試せる的です。Blueprintの変数とCustom Eventを作れることを前提に、シングルプレイで進めます。
- Blueprint Classを新規作成し、親に「Character」を選び、
BP_HitFeedbackDummyと命名します。Characterは、歩行や落下の仕組みを持ったActor です。後で使うLaunch Characterに必要なので、通常のActorを選ばないでください。 - 「Static Mesh」コンポーネントを追加し、
Bodyと命名します。Capsule Componentの子にして、メッシュをCube、Scaleを(0.6, 0.6, 1.8)、Locationを(0, 0, -6)にします。Cubeが見つからない場合は「Show Engine Content」をONにし、Engine/BasicShapes/Cubeを選びます。 - Capsule ComponentのRadiusを
42、Half Heightを96にします。Collision Presetは「Pawn」をもとに「Custom」へ変え、Visibilityの応答をBlock にします。攻撃の線が、このカプセルに当たるようにする設定です。 - BodyのCollision Presetは「NoCollision」、Simulate PhysicsはOFFにします。移動と衝突はカプセル側へ任せます。
- Class DefaultsでCan Be DamagedをON、Auto Possess PlayerとAuto Possess AIを「Disabled」にします。Character Movementでは Run Physics With No ControllerをON にします。AIを付けない的でも、移動や落下を更新させるためです。
- コンパイルしてレベルに置きます。カプセルの中心を床から約100cm上へ置き、プレイヤーから約300cm離します。以前の練習用の箱があれば、攻撃の線に重ならない場所へ移してください。

まずは的に向かって歩いてから E を押し、デバッグ用の線が的に当たることを確かめます。攻撃の向きはカメラではなく、キャラクターの正面です。この段階では、的が動かなくても構いません。
これから作る3つの演出は、すべて BP_HitFeedbackDummy のEvent Graphに置きます。最後に命中イベントからまとめて呼び出します。
画面シェイク:短く、小さく揺らす
まずは見た目の変化が分かりやすい、画面の揺れから作ります。Camera Shake は、カメラへ一時的な位置・回転などの変化を加える仕組みです。今回は上下に少しだけ首を振るような、短い回転の揺れを使います。
揺れ方をアセットにする
- Blueprint Classの作成画面で「All Classes」を開き、
CameraShakeBaseを検索して親に選びます。名前はCS_HitFeedbackにします。 - 開いたBlueprintのClass Defaultsで「Root Shake Pattern」を「Perlin Noise」にします。これは、揺れ方を作る方式の一つです。
- 次の値を設定してコンパイル・保存します。項目はRoot Shake Patternの中を展開して探します。
| 設定 | 最初の値 | 意味 |
|---|---|---|
| Single Instance | ON | 連打で揺れを何個も重ねず、同じ揺れを再スタートする |
| Duration | 0.15 | 揺れ全体の長さ。単位は秒 |
| Blend In Time / Blend Out Time | 0.02 / 0.08 | 揺れ始め・終わりをなだらかにする時間 |
| Rotation → Pitch → Amplitude | 1.0 | 上下へ向きを変える揺れ幅 |
| Rotation → Pitch → Frequency | 25 | 揺れの細かさ |
| Rotation → Yaw / Roll → Amplitude | どちらも 0 | 左右への首振りと傾きを加えない |
| Location → X / Y / Z → Amplitude | すべて 0 | カメラの位置は揺らさない |
| FOV → Amplitude | 0 | 画角は変えない |
RotationのAmplitude MultiplierとFrequency Multiplierは 1 のままにします。Amplitudeは揺れ幅、Frequencyは揺れの細かさ です。最初は揺れ幅だけを変えると、違いをつかみやすくなります。

的からカメラへ揺れを送る
BP_HitFeedbackDummy に、引数なしのCustom Event PlayLocalHitShake を作ります。ここでいうCustom Eventは、後から名前で呼び出せる処理の入口です。
白い実行ピンを Start Camera Shake へつなぎ、Shake Classに CS_HitFeedback、Scaleに 0.5、Play Spaceに「Camera Local」を指定します。Scaleは、この1回の揺れを何倍にするかという値です。
Targetには Get Player Camera Manager のReturn Valueをつなぎ、Player Indexは 0 にします。Player Camera Managerは、プレイヤーが見るカメラを管理するもの です。的自身をTargetにするのではなく、この管理役へ「画面を揺らして」と伝えます。

途中確認として、Event Graphに Event AnyDamage を置き、白線を PlayLocalHitShake の呼び出しへつないでください。Playして的を攻撃し、当たったときに画面が少し揺れれば成功です。確認後、この白線を外します。最後に3つを呼ぶ接続へ置き換えます。
ノックバック:攻撃者から離れる方向へ飛ばす
次は的を押し出します。Launch Character は、Characterに速度を与えるノードです。指定した速度は次のCharacter Movementの更新で使われ、CharacterはFalling、つまり空中で落下する状態へ移ります。
今回は地面を滑らせるのではなく、少し浮いて後ろへ飛ぶ反応にします。まず、飛ばす向きを作りましょう。
位置の差から、飛ばす向きを作る
攻撃者が的の左にいるなら右へ、右にいるなら左へ飛ばします。そのため、「的の位置 − 攻撃者の位置」 で、攻撃者から的へ向かうベクトルを作ります。ベクトルは、ここでは「どちらへ、どれだけ進むか」を表す矢印だと思ってください。

BP_HitFeedbackDummyにCustom EventApplyHitKnockbackを作り、入力SourceActorを追加します。型は Actor Object Reference です。攻撃してきた相手を、この入力で受け取ります。Get Actor Locationを2つ置き、一方はTargetをSelf、もう一方はCustom Eventに追加されたSourceActorの青い出力ピンにつなぎます。- Vectorの減算で、上側のAにSelfの位置、下側のBにSourceActorの位置をつなぎます。逆にすると、攻撃者へ引き寄せてしまいます。
- 減算の結果を
Normalize 2D (Vector)のAへつなぎます。これは上下の差を除き、水平方向の長さを1にそろえる処理です。相手との距離で吹き飛ぶ勢いが変わらないようにし ます。 - 結果をFloatの
600倍し、Vectorの加算で(0, 0, 150)を足します。水平方向へ600、上向きへ150の速度になります。単位はcm/秒で、600cm飛ぶという距離の指定ではありません。

向きが決まったら、そこへ強さを足します。

2枚の図は、Normalize 2D (Vector) のReturn Valueから、VectorとFloatの掛け算のVector入力へつなげます。
速度をCharacterへ渡す
ApplyHitKnockback の白線を Launch Character へつなぎ、TargetをSelf、Launch Velocityを上で計算したVectorにします。「XY Override」と「Z Override」は両方ONにしてください。Overrideは上書きという意味で、今の移動速度に足さず、指定した速度へ置き換えます。

途 中確認では、Event AnyDamage の白線を ApplyHitKnockback の呼び出しへ、Damage CauserをSourceActorへつなぎます。Damage Causerは、攻撃側のApply DamageでSelfとして渡した攻撃者です。この練習用の攻撃なら、ここにプレイヤーが入ります。
Playして的を攻撃し、少し浮いてプレイヤーから離れる方向へ飛べば成功です。反対側から当てて、飛ぶ向きも変わることを確かめましょう。確認後は、この一時的な接続も外します。
ヒットストップ:的の動きを一瞬だけ遅くする
最後に、命中した瞬間だけ的の動きを遅くします。押し出される動きの出だしを短く引き延ばすことで、当たった瞬間を見せる狙いです。今回は完全停止ではなく、的を0.07秒だけ、通常の0.05倍の速さにする 方法を使います。
全体ではなく、的の時間倍率を変える
Time Dilation は、時間の進み方に掛ける倍率です。1 が通常、0.5 なら半分の速さです。UEにはワールド全体を変えるGlobalと、Actorごとに変えるCustomがあります。
| 設定 | 主な使いどころ | 今回は? |
|---|---|---|
| Global Time Dilation | ワールドの動きをまとめてスローにする | 1 のまま |
| Custom Time Dilation | 特定ActorのTickやCharacterの移動などを遅くする | 的だけを 0.05 にする |
Tickは、ゲームの進行に合わせて繰り返し動く更新処理です。Custom Time Dilationは、このActorに渡す経過時間を変えます。Actorに関係する音・タイマー・物理演算まで、何もかも同じ倍率になるわけではありません。今回はCharacter Movementで動く的に使います。

戻す処理には Set Timer by Event を使います。これは 指定した時間が来たら、つないだイベントを呼ぶ予約 です。予約後も次の処理へ進めるので、画面シェイクやノックバックを同じ命中時に始められます。
このタイマーは、的のCustom Time Dilationでは遅くなりません。ただしGlobal Time Dilationやゲームのポーズの影響は受けます。今回はGlobalを 1 に保ち、ポーズしていない状態で試してください。「Timerなら時間変更の影響を受けない」という意味ではありません。
元の速さを覚え、復帰を予約する
BP_HitFeedbackDummy に、次の変数を作ります。
| 変数 | 型 | 初期値 | 役割 |
|---|---|---|---|
SavedTimeDilation | Float | 1 | 遅くする直前の倍率を覚える |
bHitStopActive | Boolean | false | すでにヒットストップ中かを覚える |
続いて、引数なしのCustom Eventを2つ、StartLocalHitStop と EndLocalHitStop という名前で作ります。Start側を次の順につなぎます。
StartLocalHitStop→Branch。ConditionにbHitStopActiveをつなぎます。Trueは未接続にし、すでに実行中なら新しいヒットストップを始めません。- False →
Set SavedTimeDilation。SelfのGet Custom Time Dilationを値へつなぎ、変更前の倍率を保存します。 - →
Set bHitStopActiveをtrueにします。 - →
Set Custom Time Dilation。TargetはSelf、値は0.05です。 - →
Set Timer by Event。Timeを0.07、LoopingをOFFにします。赤いEvent入力へEndLocalHitStopの赤いデリゲート出力をつなぎます。デリゲートは、タイマーに「後で呼ぶイベント」を渡すためのピンです。

保存できたら、実際に遅くして戻す予約を入れます。

画像は一つのグラフを前後に分けています。前半の Set bHitStopActive の実行出力を、後半の Set Custom Time Dilation の実行入力 へつないでください。EndLocalHitStop は、次の復帰処理でも同じイベントを使います。
時間が来たら、保存した速さへ戻す
EndLocalHitStop の白線を Set Custom Time Dilation へつなぎます。TargetはSelf、値には SavedTimeDilation を渡します。その後、Set bHitStopActive をfalseにすれば、次のヒットストップを受け付けられます。

ここで固定の 1 を書かないのは、もともと別の速度だった場合にも戻せるようにするためです。また、ヒットストップ中に何度も保存すると、元の値が 0.05 で上書きされてしまいます。最初のBranchは、それを防いでいます。
戻す処理を各的に持たせる のも大事な点です。攻撃側の「最後に当たった相手」だけを覚える変数に頼ると、別の的に当てたとき、先の的を戻せなくなることがあります。この組み方なら、それぞれの的が自分の倍率を覚えて戻します。
命中した瞬間に、3つを呼び出す
3つの演出ができたので、BP_HitFeedbackDummy の Event AnyDamage からつなぎます。
Event AnyDamage→Branch。ConditionにはDamage > 0をつなぎます。- True → 実行ピン付きの
Is Valid。Input ObjectにはDamage Causerを渡します。これは、攻撃者として渡されたActorが使えるかを確かめるノードです。 - Is Valid →
Sequence。無効の場合と、最初のBranchのFalseは未接続で構いません。 - SequenceのThen 0 →
StartLocalHitStop、Then 1 →PlayLocalHitShake、Then 2 →ApplyHitKnockbackの呼び出しへつなぎます。Then 2は「Add pin」で追加します。 ApplyHitKnockbackのSourceActorへ、Event AnyDamageのDamage Causerをつなぎます。3つの呼び出しのTargetはすべてSelfです。

もう1つ、攻撃した相手が有効かも確かめます。

2つの確認を通ったら、3つの演出をまとめて呼びます。

3枚の図は、BranchのTrue → Is Validの実行入力、Is Validの成功側 → Sequenceの実行入力という順でつなぎます。青いDamage Causerの線は、Is Validの 確認とSourceActorへの受け渡しの両方に使います。
Sequenceは白線を複数の処理へ順番に流すノード です。Then 0でタイマーを予約した後、その満了を待たずにThen 1、Then 2へ進みます。そのため、揺れと吹き飛びも今回の命中で始まります。
Playして攻撃すると、画面が小さく揺れ、的は出だしだけゆっくり動いてから後方へ飛びます。ヒットストップが分かりにくければ、TimerのTimeを一時的に 0.3 に伸ばすと、遅い動きから通常の動きへ戻る境目を確認しやすくなります。確認後は 0.07 へ戻してください。
この的は練習用なので、正のダメージを受け取れば演出を出します。実際の敵に無敵時間やガードを付けたら、本当にダメージを受け付けた処理の後 へ、この3つの呼び出しを移します。Event AnyDamageが来ただけで、必ずHPが減るとは限らないためです。
やりすぎの見分け方
完成したら、演出を全部付けたまま強くする前に、一つずつ外して比べてみましょう。Playを止め、Sequenceから各演出へ向かう白線を1本外して再生すると、その演出の役割を確かめられます。比べ終えたら接続を戻します。
| 比べること | 見るところ | 調整する場所 |
|---|---|---|
| ヒットストップのあり・なし | 命中が見やすくなるか、攻撃の流れが重くなるか | TimerのTimeを 0.07 → 0.04 へ |
| 揺れのあり・なし | 衝撃が伝わるか、相手を見失うか | Start Camera ShakeのScaleを 0.5 → 0.25 へ |
| 吹き飛びのあり・なし | 当たった相手が分かるか、次の攻撃が届かなくなるか | 水平方向の倍率を 600 → 300 へ |
強い演出がいつも良いとは限りません。例えば連続攻撃では、相手が遠くへ飛びすぎると2発目を当てにくくなります。通常攻撃は弱めにして、とどめだけ強くすると、操作を邪魔せず違いを出せます。

的を複製して2体へ続けて攻撃し、両方が元の速さへ戻ることも確かめてください。今回の組み方では、ヒットストップ中の追加命中で時間を延長しません。最初の命中から0.07秒後に戻り、画面シェイクとノックバックは追加命中でも呼ばれます。
光・音・数字を足したくなったら
3つの反応ができたら、別の情報も足せます。何を伝えたいかを決めてから選ぶと、見た目だけが騒がしくなりにくくなります。
| 足したい反応 | 伝わること | 作り方 |
|---|---|---|
| 的を短く光らせる | どの相手に当たったか | Material Instanceによる色の変更 |
| 命中音を鳴らす | 視線が少し外れていても命中が分かる | 効果音の再生 |
| 火花を出す | どこへ当たったか | Niagaraで作るヒットエフェクト |
| ダメージ数値を出す | どれくらい効いたか | フローティングダメージ表示 |
まずは一つ足し、同じ攻撃を何度か試してみてください。音・光・数字をすべて追加しなくても、伝えたいことが読み取れれば十分です。

おまけ:先に知っておくと良いこと
- Anim Notifyと命中は別です。 Notifyは、攻撃アニメーションのどの位置で判定を出すかを知らせます。そのタイミングでTraceやOverlapを調べ、相手に当たってダメージを受け付けたときに、今回の演出を呼びます。
- TimerのTimeは正の値にします。
0以下ではタイマーが解除されます。ヒットストップを無効にするためにTimeを0へ変えると、倍率だけ下げたまま復帰を予約できなくなります。比較するときは呼び出しの白線を外してください。 - Custom Time Dilationを別の処理からも変えるなら、調整が必要です。 例えばヒットストップ中にスロー魔法が切れる場合、古い倍率を戻すだけでは状態が食い違い ます。今回の実践では、この的の倍率を書き換える処理をヒットストップだけにしています。
- Launch Characterは移動状態も変えます。 AIの移動指示や床を滑る動きへ組み込む場合は、吹き飛び中の追跡を止めるなど、通常移動との兼ね合いも確認します。物理シミュレーション中の箱には別の仕組みが必要です。
- 画面シェイクはプレイヤーごとの演出です。 今回のPlayer Index 0は、シングルプレイで使う最初のローカルプレイヤーです。マルチプレイではダメージを処理する側と、画面を揺らす側を分けます。揺れの強さを設定で下げたり、OFFにできたりするようにすると調整しやすくなります。
公式資料:Camera Shakes、Start Camera Shake、Launch Character、Gameplay Timers。実践はこれらの仕様をもとにしたBlueprint例で、UE実機での動作確認は未実施です。
まとめ
攻撃の手応えは、命中したことをプレイヤーへ伝える反応から作れます。今回は、短いスローで当たった瞬間を見せ、画面シェイクで衝撃を加え、ノックバックで力の向きを表しました。
最初は練習用の的で一つず つ確かめ、最後に命中処理へまとめます。演出を足すだけでなく、外した状態とも比べると、自分のゲームに必要な強さが見えてきます。