攻撃ボタンを押した瞬間にダメージを与えると、まだ振りかぶっているのに敵へ当たってしまいます。反対に、アニメーションが終わるまで待つと、剣が通り過ぎたあとにHPが減ります。攻撃らしい手触りを作るには、動きの中の「当たってよい区間」 を決める必要があります。
そこで使うのが Animation Montage と Anim Notify です。Montageで攻撃を再生し、その途中に置いたNotifyから「ここで判定を開く」「ここで閉じる」と知らせます。この記事では、左クリックで攻撃し、目の前のダミーへ1回だけ20ダメージを与えるところまで作ります。

この記事でわかること
- Montage・Slot・Notifyがそれぞれ何を担当するか
- Notifyで「当たる区間」だけを決める方法
- 区間に合わせて判定を開閉し、同じ相手に1度だけダメージを送る手順
- 再生が中断されたときに判定を閉じ忘れない書き方
この記事で作るもの
- 左クリックで攻撃を再生し、終わったら移動のアニメーションへ戻る
- 振り下ろす区間だけ、前方の箱で相手を検出する
- 同じ攻撃では同じ相手に1度だけ当て、中断 したときも判定を閉じる
Montage・Slot・Notifyは何を担当する?
まず、攻撃に登場する名前を整理します。Animation Sequence は、剣を振る、腕を伸ばすといった動きそのものの素材です。Animation Montage は、その素材を並べ、再生する区間や途中の通知を付けるアセットです。
キャラクターへMontageの動きを渡す入口が Slot です。Animation BlueprintのAnimGraphへSlotノードを挿しておくと、通常の移動ポーズに代わって攻撃のポーズを出せます。ポーズ は、その瞬間の体の姿勢を指します。
そして Anim Notify は、動きの途中で処理を呼ぶための目印です。「振り 下ろしが始まったら判定を出す」「足が着いたら音を鳴らす」といったタイミングを、アニメーションを見ながら決められます。
| 仕組み | 今回の担当 |
|---|---|
| Animation Sequence | 攻撃の動きの素材 |
| Animation Montage | 攻撃素材を再生し、途中や終了を知らせる |
| Slot | MontageのポーズをAnimGraphへ通す |
| Anim Notify | 当たり判定を出す区間を知らせる |
| CharacterのBlueprint | 入力を受け、判定を切り替え、ダメージを送る |
歩行や走行は、これまでどおり State Machine で切り替えます。State Machineでも攻撃は作れますが、Montageを使うと、Character側から「今、攻撃を始める」と指示し、その終了や中断も受け取れます。今回はこの組み合わせを使います。

攻撃素材からMontageを作る
先に用意するもの
UE5.6のThird Personプロジェクトを使い、Animation Blueprintの記事で作った ABP_Player と Locomotion を土台にします。操作する BP_ThirdPersonCharacter の Mesh に、ABP_Player が設定されている状態です。
追加で、MannyのSkeletonで再生できる攻撃のAnimation Sequenceを1本 用意します。Skeletonは骨の名前やつながりを持つアセットです。別のキャラクター向け素材は、そのままでは使えないことがあるため、必要ならリターゲットの記事でManny用へ変換してください。
今回は、その場で動作する In Place の素材を使います。剣のモデルはなくても構いません。まずは前方の箱を使い、「攻撃の動きとダメージのタイミングが合うか」を確かめます。実践は単独プレイを前提にします。
AM_Attackを作る
- 攻撃のAnimation Sequenceを開き、Mannyで動きが再生できることを確認します。
- コンテンツブラウザでその素材を右クリックし、「Create」→「Create AnimMontage」を選びます。名前を
AM_Attackにします。 AM_Attackを開き、SlotトラックがDefaultGroup.DefaultSlotになっていることを確認します。- トラック内の攻撃素材を選び、「Loop Count」を
1にします。Sectionは最初のDefaultだけを使い、自分自身へつながるループを作りません。 - 「Asset Details」で「Enable Auto Blend Out」をオンにします。「Blend In」と「Blend Out」の「Blend Time」は、最初はそれぞれ
0.1秒にします。
ブレンド は、2つのポーズを徐々に混ぜて切り替えることです。Blend Inは移動から攻撃へ、Blend Outは攻撃から移動へ戻す時間です。自動のBlend Outを有効にすると、今回のような単発の攻撃が終わったあと、元のポーズへ戻れます。
Montageはループ再生もできるため、「Montageなら必ず1回で終わる」というわけではありません。まずは上の設定で、単発の攻撃を作ります。

Slotを挿して、クリックで再生する
AnimGraphに攻撃の入口を作る
ABP_Player のAnimGraphを開き、Locomotion と Output Pose の間へ Slot ノードを挿します。右クリック検索で Slot を探し、追加したノードの「Slot Name」を DefaultSlot にします。

白いポーズの線を、Locomotion → Slot 'DefaultSlot' → Output Pose の順につなぎます。Slotの「Always Update Source Pose」もオンにします。これで攻撃を表示している間も、土台の移動ポーズを更新し続けられます。
Montage側の DefaultGroup.DefaultSlot と、この DefaultSlot が対応します。SlotへMontageのアセットを配線するわけではなく、同じSlot名を通じて動きが届く 仕組みです。コンパイルして保存します。
入力からPlay Montageを呼ぶ
IA_Attack というInput Actionを作り、「Value Type」をBooleanにします。既存の IMC_Default へ左マウスボタンの割り当てを追加します。入力アセットの作り方や、Mapping Contextが有効になっているかの確認はEnhanced Inputの記事を参照してください。
BP_ThirdPersonCharacter に、次の変数を作ります。b で始まる2つは、オン・オフを覚えるBooleanです。
| 変数 | 型 | 初期値 | 何を覚える? |
|---|---|---|---|
bIsAttacking | Boolean | false | 攻撃の再生中か |
bHitWindowOpen | Boolean | false | ダメージを与えてよい区間か |
HitActors | Actor Object Referenceの配列 | 空 | 今回の攻撃ですでに当たった相手 |
配列は複数の相手を入れるリストです。Object Reference は「レベルにいる、この1体」を指す参照です。HitActors は変数の型をActorの「Object Reference」にし、型の横でコンテナを「Array」に変えます。敵の種類ではなく、今回当たった個々の相手を記録します。
Event Graphへ IA_Attack のイベントを置き、次の順につなぎます。
StartedからBranchへ進み、ConditionへbIsAttackingをつなぎます。FalseからSet bIsAttackingをtrueにします。True側は接続せず、攻撃中の再入力を無視します。HitActorsのGetからClearを作り、リストを空にします。- 続けて Play Montage を置きます。Componentsの
MeshをGetで持ってきて「In Skeletal Mesh Component」へつなぎ、「Montage to Play」をAM_Attackにします。

ここまでで「攻撃していないときだけ開始する」という入口ができます。続くClearは前回の命中記録を消す処理です。これがないと、次の攻撃でも「すでに当たった相手」と判断してしまいます。

「Play Rate」は 1、「Starting Position」は 0、「Starting Section」は None のままです。Started はボタンを押したときの入口なので、押しっぱなしで毎フレーム攻撃を始めることを避けられます。
ここでは、Play Montage の On Completed と On Interrupted を、それぞれ Set bIsAttacking = false へつなぎます。どちらの経路でも次の攻撃を受け付けるためです。後ほど、この2か所を判定の後始末もする FinishAttack に置き換えます。

ここで一度プレイしてください。 左クリックで攻撃し、終了後に歩き直せれば、素材・Slot・再生の入口はつながっています。まだダメージは発生しません。
Notifyで「当たる区間」を決める
点で知らせるか、区間で知らせるか
Montage専用のNotifyには、1つの時刻を知らせる Montage Notify と、開始から終了までの幅を持つ Montage Notify Window があります。足音なら1点、当たり判定なら区間として置くと、意図を読み取りやすくなります。
今回は Montage Notify Window を1つ置き、名前を HitWindow にします。AM_Attack を開き、再生位置を動かしながら、振り下ろしの始まりと終わりを探してください。

- タイムラインの「Notifies」の下にある通知トラックで右クリックします。
- 「Add Notify State」→「Montage Notify Window」を選びます。「Add Notify」から作る点の通知とは入口が異なります。
- 追加した区間を選び、「Details」の「Notify Name」を
HitWindowにします。トラックの名前ではなく、通知自身の名前 です。 - 区間の左端と右端を動かし、判定を出したい動きに合わせます。たとえば全長1秒なら、開始
0.20秒、終了0.45秒です。数値を入れる場合、右クリックの「Notify Begin Time」を0.20、「Anim Notify State Duration」を0.25にします。 - 「Montage Tick Type」は「Branching Point」にします。今回は、区間の境目に合わせてゲーム処理を呼ぶことを優先します。
0.20〜0.45秒は説明用の例です。素材の長さが違っても同じ数値を入れるのではなく、腕や武器の動きに合わせます。振りかぶりを含めすぎると、見た目より先に当たるようになります。
通知はPlay Montageへ戻ってくる
Play Montage は、再生中に起きたことを右側の出力ピンで知らせます。あとから呼ばれるこれらの出力を コールバック と呼びます。
| 出力 | 呼ばれるとき | このあとつなぐ処理 |
|---|---|---|
On Notify Begin | HitWindow の開始 | 判定を開く |
On Notify End | HitWindow の終了 | 判定を閉じる |
On Blend Out | 通常終了に向けて、攻撃のポーズを抜き始める | 判定を閉じる |
On Completed | 中断されずに再生とBlend Outが終わる | 判定を閉じ、次の攻撃を許可する |
On Interrupted | 再生が中断された、または再生できなかった | 判定を閉じ、次の攻撃を許可する |
ノード最上部の名前のない実行出力は、再生の要求を出した直後に進む入口です。攻撃の終了を待つ出力ではない ので、ここへ後始末をつながないでください。
On Notify Begin / End が反応するのはMontage専用の通知です。「New Notify」でSkeletonへ登録する通常の通知は、Animation Blueprint側のイベントで受け取ります。また、名前が似ている Play Anim Montage には今回使う通知の出力がありません。ノード名を Play Montage にそろえます。
前方の判定と、HPを持つダミーを作る
AttackHitboxを前へ置く
BP_ThirdPersonCharacter で、Capsule Componentの子に Box Collision を追加し、AttackHitbox と名付けます。今回は武器の骨へ付けず、キャラクターの前方に置きます。

| AttackHitboxの設定 | 値 |
|---|---|
| 相対Location | X=80、Y=0、Z=0 |
| 相対Rotation / Scale | (0, 0, 0) / (1, 1, 1) |
| Box Extent | X=40、Y=40、Z=50 |
| Collision Presets | いったん OverlapAllDynamic を選ぶ |
| Collision Enabled | そのあと No Collision へ変更する |
| Generate Overlap Events | オン |
| Hidden in Game | 確認中はオフ |
Extent は箱の中心から端までの長さです。この設定では全体が80×80×100cmになります。X方向へ80cm離した位置が箱の中心なので、正面に立つ相手へ届く範囲になります。箱が足元や背後へ出ていないか、Blueprintのビューポートでも確かめます。
Overlap は、相手を押し返さずに重なりを検出することです。今回は当たったかどうかだけを知りたいので、攻撃中は Query Only に切り替えます。普段は No Collision にして、重なりの検出自体を止めます。設定を変更するとPresetがCustom表示になっても、各項目が上の値なら構いません。
Hidden in Game をオフにした箱の線は、判定を閉じていても表示されます。線が見えることと、ダメージを与えられることは別 です。
ダミーのHPを減らして表示する
Actorを親にしたBlueprint BP_TrainingDummy を作ります。ComponentsへCubeを追加し、Scaleは (1, 1, 1) のままにします。Cubeの「Collision Presets」を OverlapAllDynamic、「Collision Enabled」を Query Only、「Generate Overlap Events」をオンにします。「Simulate Physics」はオフです。
AttackHitbox とCubeの 両方 で重なりの通知を有効にするのが要点です。「Class Defaults」の「Can Be Damaged」もオンにします。
Float型の変数 HP を作り、初期値を 100 にします。Event Graphに Event AnyDamage を追加し、Damageの値を現在のHPから引いて保存します。

白い実行線は Event AnyDamage → Set HP → Print String の順です。Set HP に入れる値は HP − Damage にします。引き算ノードの上側Aへ現在のHP、下側BへイベントのDamageをつなぎます。
保存したあと、HPをGetで読み直し、Print String の「In String」へつなぎます。接続するとFloatを文字列へ変換するノードが入ります。「Duration」を 10 秒にしておくと、減ったHPを見逃さずに確認できます。

この例では死亡処理を付けず、HPの変化を見るだけにします。ダミーをレベルへ配置し、Cubeが床に半分埋まらないよう、中心を床から50cmの高さへ置きます。プレイヤーが近づいて、前方の判定箱をCubeへ重ねられる位置にします。
区間に合わせて判定を開閉する
判定を閉じる処理は、区間の終わりだけでなく中断時にも使います。何か所にも同じノードを並べず、Character側に 関数 としてまとめます。関数は、一まとまりの処理に名前を付けて呼び出せるものです。
BP_ThirdPersonCharacter の「My Blueprint」→「Functions」の「+」で、次の3つを作ります。入力や戻り値は不要です。
OpenHitWindowとCloseHitWindow

OpenHitWindow:Set bHitWindowOpen = true → Set Collision Enabled。TargetはAttackHitbox、New TypeはQuery Only。CloseHitWindow:Set bHitWindowOpen = false → Set Collision Enabled。TargetはAttackHitbox、New TypeはNo Collision。
Set Collision Enabled は、Componentsの AttackHitbox をGetで出し、その青いピンから検索すると作れます。開くときは Booleanを先にtrueにします。判定を有効にした時点で重なりが通知されても、これから作るダメージ処理が「区間外」と判断しないためです。
FinishAttackで後始末をそろえる
FinishAttack は CloseHitWindow → Set bIsAttacking = false とつなぎます。CloseHitWindow は何度呼んでも閉じた状態になるので、Notify Endと終了通知の両方から呼ばれても構いません。

Event Graphの Play Montage へ戻り、出力を次のようにつなぎます。
On Notify BeginからSwitch on Nameを作ります。ノードを選び、Detailsの「Pin Names」の「+」で項目を追加し、名前をHitWindowにします。Play Montageのピンク色のNotify Nameを「Selection」へつなぎ、HitWindow側からOpenHitWindowを呼びます。On Notify Endにも 別のSwitch on Nameを置き、同じNotify NameをSelectionへつなぎます。HitWindow側からCloseHitWindowを呼びます。On Blend OutからCloseHitWindowを呼びます。- 先ほど
On CompletedとOn InterruptedにつないだSetノードを、それぞれFinishAttackの呼び出しに置き換えます。

Switch on Name は、届いた名前に合う出口だけを通すノードです。別の通知を追加しても、それを攻撃判定の合図と取り違えないようにしています。
次の図は、同じ Play Montage の終了に関わる出力を抜き出しています。再生ノードをもう1つ増やす必要はありません。

中断されると、タイムライン上の予定どおりに最後まで進むとは限りません。そこで 区間の終了通知だけに後始末を任せず、再生が終わる側からも閉じます。これで、攻撃が止まったのに判定だけ残る状態を防ぎます。
同じ相手には1度だけダメージを送る
重なった相手を1つの処理へ渡す
AttackHitbox を選び、Detailsの「Events」で On Component Begin Overlap の「+」を押します。これは 相手との重なりが始まったとき のイベントです。重なっている間、毎フレーム呼ばれるものではありません。
Character側に TryHitTarget という関数を作り、入力 TargetActor をActor Object Reference型で追加します。重なりイベントの Other Actor を、この入力へ渡します。Other Actorは「今、箱へ重なった相手」です。
入力を追加するには、関数の入口ノードを選び、Detailsの「Inputs」の「+」を使います。関数内では、入口にできた TargetActor の青いピンから線を引いて使えます。図のように離れた場所で読む場合は、右クリック検索の Get Target Actor を使います。Characterの変数をもう1つ作る必要はありません。

区間外・ダミー以外・登録済みの相手を除く
TryHitTarget の中で、次の順に確認します。
BranchのConditionへbHitWindowOpenを入れ、Trueだけを先へ進めます。Cast To BP_TrainingDummyを置き 、ObjectへTargetActorをつなぎます。成功側だけを進めます。これで、自分自身や床などへダメージを送らず、今回のダミーだけを対象にできます。HitActorsのGetから Contains を作り、ItemへTargetActorを入れます。Containsは「この相手がリストに入っているか」を調べます。- そのBoolean出力を次の
BranchのConditionへつなぎ、False側だけ をダメージ処理へ進めます。Trueなら、この攻撃ですでに当たっています。

ここで確認したのは「今は判定を出してよいか」「相手はダミーか」の2点です。Castの成功側から、次のContainsを使った確認へ進みます。

ダミーが一度箱の外へ出て入り直した場合や、相手に複数の判定部品がある場合は、重なり開始の通知が再び届くことがあります。そのたびにHPを減らさないための確認です。
記録してからApply Damageを呼ぶ
未登録だった相手を HitActors の Add で追加し、続けて Apply Damage を呼びます。AddのItemとApply Damage のDamaged Actorには、どちらも TargetActor を渡します。

| Apply Damageの入力 | 設定 |
|---|---|
| Damaged Actor | TargetActor |
| Base Damage | 20 |
| Event Instigator | Get Controller の戻り値 |
| Damage Causer | Self |
| Damage Type Class | DamageType |
Event Instigatorは「誰の操作による攻撃か」を示すController、Damage Causerは「直接ダメージを起こしたActor」です。今回は操作中のCharacterが攻撃するので、上の値を使います。
Apply DamageがHP変数を直接探して減らすわけではありません。 受け取ったダミーの Event AnyDamage が呼ばれ、そこでHPを引き算します。送る側と受ける側をつなぐと、最初の攻撃で100→80になる流れが完成します。
HitActors は次の攻撃の開始時にClearされるので、同じダミーへもう一度攻撃すれば60になります。1体へ1回という制限なので、箱の中にダミーが2体あれば、それぞれに20ダメージを与えられます。
動かして確かめる
コンパイルして保存し、まずはダミーを1体だけ置いて試します。
- 攻撃せずに重なる:前方の箱がCubeに触れても、HPは表示されません。
- その場で1回攻撃する:振り下ろす区間 で
80が1度だけ表示されます。ボタンを押し続けても攻撃を繰り返しません。 - 終了後、もう一度攻撃する:今度は
60が表示されます。 - 箱の外から攻撃する:届かない距離ではHPが変わりません。

次は HitWindow の開始を少し早めて比べます。0.20秒だったものを0.10秒へ動かすと、見た目がまだ振りかぶりでもダメージが入り始めます。元へ戻すと、「当たる瞬間」をどこへ置くと自然かを比べられます。最初に全長1秒以外の素材を選んだ場合も、区間の開始を少しだけ前後させてみてください。
中断時も閉じるか確認する
確認用に、CharacterのEvent Graphへキーボード K のイベントを置き、Pressedから Montage Stop を呼びます。Mesh → Get Anim Instance の戻り値をTargetへつなぎ、Montageを AM_Attack、In Blend Out Timeを 0.1 にします。

一時的に Play Montage のPlay Rateを 0.25 にすると、攻撃がゆっくりになり、判定中にKを押しや すくなります。中断後にダミーへ近づいてもHPが減らず、次の左クリックではまた攻撃できることを確認します。確認後はPlay Rateを 1 に戻し、Kの確認用ノードは外します。
うまく動かないとき
| 症状 | 戻って確かめる場所 |
|---|---|
| 左クリックに反応しない | IA_Attack のStarted直後へPrint Stringを置く。IMC_Defaultへの割り当てと有効化を確認 |
| 攻撃の見た目だけ変わらない | 操作キャラのMeshに使うAnim Class、Slot名の一致、Output Poseまでの接続、素材のSkeleton |
| 動くが判定が開かない | Montage Notify Windowを作ったか、Notify NameがHitWindowか、Play Montageを使っているか |
| 判定を開いてもHPが減らない | 両側のGenerate Overlap Events、Cubeとの実際の重なり、ダミーのCan Be Damaged、Castの成功 |
| 1回の攻撃で何度も減る | ContainsのFalseだけがAdd→Apply Damageへ進んでいるか。Clearを重なりイベントへ置いていないか |
| 1回攻撃すると次が出ない | CompletedとInterruptedの両方がFinishAttackへ進むか。Auto Blend Outがオンか、Sectionがループしていないか |
| 中断後も当たり続ける | Interrupted→FinishAttack→CloseHitWindowの接続と、Set Collision EnabledのTarget |
おまけ:コンボや上半身の攻撃へ広げる
Sectionは「次にどの区間を再生するか」を決める
Section は、Montageのタイムラインへ付ける区切りです。たとえば攻撃素材を3本並べ、各開始位置に Attack1、Attack2、Attack3 と名前を付けると、次へつなぐ攻撃を指定できます。追加はSlotトラッ クの右クリックから「New Montage Section」です。

「追加入力があれば次の攻撃へ、なければ終了」にするなら、まずMontage Sectionsパネルで各Sectionの次を None にし、自動で次段へ進むつながりを外します。そのうえで、入力を受け付ける区間にボタンが押されたら、Montage Set Next Section で現在のSectionの次を予約します。
Montage Jump to Section はその場で指定区間へ飛ぶので、「今の振りを終えてから次へ」とは結果が異なります。どちらを使うかは、攻撃を最後まで見せたいか、途中から切り替えたいかで決めます。
これは単発攻撃が動いたあとの拡張です。今回の bIsAttacking は攻撃中の入力を無視するため、コンボでは追加入力を記録する処理が必要です。また、次段でも同じ相手へ当てるなら、HitActors を各攻撃の開始で空にするよう変更します。
Slot名を変えるだけでは上半身に限定されない
今回のSlotは全身のポーズを差し替えます。走りながら上半身だけ攻撃させるには、Slot名を UpperBody にするだけでなく、Layered Blend per Bone などで「どの骨から上へ攻撃を混ぜるか」を設定します。
同時再生の制約にも Slot Group が関わります。これはSlotをまとめるグループで、同じグループの別Montageを再生すると、先に再生していたものが中 断されます。Slot名だけを分けて同じグループへ入れても、独立した同時再生にはなりません。
前方の箱から、武器の軌道へ
この箱はCharacterの前方へ固定しているため、剣の先端を追いかけません。武器の形に合わせたいときは、骨に付けるSocketへ判定を取り付けたり、武器が前のフレームから動いた範囲をTraceで調べたりする方法へ進めます。
攻撃で前へ踏み込む移動まで素材に含めたい場合は Root Motion が別の題材になります。まずはIn Placeのまま「再生・通知・ダメージ」の流れを完成させてから、移動の扱いを足すと原因を切り分けやすくなります。
まとめ
Montageは攻撃を再生し、Slotはその動きをキャラクターへ通し、Notifyは判定を開閉するタイミングを知らせます。ダメージを送る処理とHPを減らす処理は、それぞれCharacterとダミーが担当します。
まずは 1回の入力で1回攻撃し、当たる区間にだけ100→80になること を確かめてください。区間の位置を変えて手触りを比べられるようになれば、次の攻撃素材でも同じ仕組みを使えます。
参考:Animation Slots、Animation Notifies、Montage Editor、Apply Damage