攻撃の処理は呼ばれているのに、敵のHPが100から減らない。Print Stringで「渡されたダメージは0」と分かっても、どの計算で0になったのかまでは見えていないことがあります。
そこで使うのが Blueprint Debugger です。怪しい処理の手前で一時停止し、少しずつ進めながら値を確かめられます。「何が起きたか」をログで確認した後に、「なぜその値になったか」を調べる道具です。
この記事では、わざとダメージ倍率を0にした小さな例を作ります。止める→値を調べる→設定を直す→HPが100から80へ減るか確かめる ところまで、一緒に追っていきます。
この記事でわかること
- ブレークポイントで、ノードの実行直前に止める方法
- Step Into・Over・Outで、調べる範囲を選ぶ方法
- ピンの値とWatchを見るときに、未実行を見分ける理由
- Debug Objectで、同じBlueprintのどの個体を見るか選ぶ方法
ログとDebuggerを、調べたいことに合わせて使う

| 調べたいこと | 使いやすい道具 |
|---|---|
| 攻撃処理が呼ばれたか、何回呼ばれたか | Print StringとOutput Log |
| どの値を使い、どちらの分岐へ進んだか | Blueprint Debugger |
| 動かしたまま、連打や時間の間隔を観察したい | ログや記録用の道具 |
どちらも値を調べられます。Debuggerでは、その都度Printを追加せずにピンや変数を確認でき、ログではゲームを止めずに経過を残せます。Print Stringの記事で怪しい場所を絞り、詳しく見たい箇所で停止する使い方もできます。
タイミングに依存する不具合は、停止やエディタへのフォーカス移動で条件が変わることがあります。止めると再現しなくなった場合は、動かしたままログを取る方法へ戻ります。
ブレークポイントは、実行する直前に止める印
ブレークポイント は、「このノードまで来たら、実行する前に止める」という印です。SetやBranch、白い実行線を持つ関数呼び出しなどへ置きます。
- 止めたいノードを右クリックし、「Add Breakpoint」を選ぶ。既定のショートカットは
F9。 - Compile・保存し、Playする。エディタ内で遊ぶこの実行方法を PIE(Play In Editor) と呼ぶ。
- その処理が呼ばれる操作をする。到達すると一時停止し、対象ノードが強調される。
大切なのは、止まったノードは、これから実行する という点です。Set Healthに止まったなら、そのSetによるHPの書き換えはまだ終わっていません。

足し算やGet変数のように、白い実行線がない 純粋なノード は、値を使う側から必要になったときに計算されます。そこへ印を置こうとするより、結果を使うSetや、計 算する関数の呼び出しで止めます。
印の状態と、Debuggerの開き方
有効な印は赤く塗られ、無効化した印は輪郭だけになります。黄色の「!」は、その場所では有効に止められない状態です。Compileで解消する場合もありますが、直らなければ印へマウスを乗せて理由を確認します。
一覧やWatchを見たいときは、メインエディタのToolsから「Blueprint Debugger」を開きます。BlueprintエディタのDebugメニューからも開けます。専用ウィンドウを開かなくても、ブレークポイント自体は動きます。
ステップ実行:入る・またぐ・出る
一時停止中は、ツールバーのステップ操作で処理を進められます。ここでは、何という名前の操作かを覚えると、キー設定の違う環境でも使えます。

| 操作 | 何が起きるか | 使う場面 |
|---|---|---|
| Step Into | 次へ進み、Blueprint関数なら中へ入る | 計算の中身を調べたい |
| Step Over | 現在の処理を実行し、関数の中を細かく追わず続きへ進む | その関数の結果だけ確かめたい |
| Step Out | 現在の関数の残りを実行し、呼び出し元の続きへ進む | 関数内の確認が済んだ |
| Resume | 通常の実行へ戻る | ゲームを続けたい |
OverでもOutでも、処理は実行されます。 過去へ戻ったり、関数の効果をなかったことにしたりする操作ではありません。途中の別のブレークポイントで、再び止まることもあります。
F10やF11などの割り当ては「Editor Preferences」→「Keyboard Shortcuts」でStep Over/Step Intoを検索して確認できます。本文の実践は、ツールバーのボタンから進めても構いません。
デバッガは巻き戻せないので、見逃した場合は手前へブレークポイントを置き、同じ操作をもう一度行います。疑わしい関数だけIntoし、確認できた関数はOverする、と範囲を選ぶと追いやすくなります。
値を見る:ピンのホバーとWatch
停止中にデータピンへマウスを乗せると、値を確認できます。ただし、表示されるのは そのノードが直近に実行されたときの値 です。まだ実行していないノードの出力に、今回の結果が入っているわけではありません。
たとえば、ダメージ計算を呼ぶ直前で止めた場合、計算結果はまだできていません。そこで「値を表示できない」と出ても、ダメージが0という意味ではありません。必要な処理を実行してから見直します。

Watch=ウォッチ は、何度も調べたいピンを一覧へ登録する機能です。ピン名を右クリックして「Watch this value」を選ぶと、Debugger側で追えます。こちらも、まだ実行されていない値は確認できません。
この違いは次の実践で使います。関数の中で計算結果を変数へ保存し、その処理が済んだところで、掛け合わせた2つの値を調べます。
Debug Object:どの個体を見るか
同じBP_Enemyを3体置いても、HPは3体それぞれが持っています。このように、Blueprintという設計図から作られた 実際の個体 をインスタンスと呼びます。

Blueprintエディタの Debug Object は、その観察対象を選ぶ欄です。まずは実践のように対象を1体にすると、別の個体の値と取り違えにくくなります。
複数体いる場合は、Play中に Shift + F1 でマウスをエディタへ戻し、Debug Objectから調べたい実行中の個体を選びます。レベルで付けたActor名を手がかりにしてください。設定や実行状態によって対象が選ばれることもあるため、「未選択だったはず」と思い込まず、現在の名前を確認します。
対象を選んでも、そのActorへ攻撃が送られるわけではありません。ゲーム内で処理を呼ぶ相手と、Debuggerで見る相手をそろえる ことが大切です。
実践:ダメージが0になる原因を調べる
Fキーを押すと、練習用の敵へ1回分のダメージ処理を送ります。最初は倍率0なのでHPが減りません。その0をDebuggerで確認してから、倍率1へ直します。

UE5のThird PersonテンプレートをBlueprintで作り、VariantがあればNoneを選びます。新しい練習フォルダで作業します。攻撃アニメーションや当たり判定は準備せず、キー入力で同じ条件を繰り返せるようにします。
① 練習用の敵と変数を用意する
Actorを親に BP_DebugDamageEnemy を作ります。DefaultSceneRootの子にStatic Meshを追加して標準Cubeを設定し、相対位置・回転を0、Scaleを1にします。Cubeは「Show Engine Content」をオンにして、Engine/BasicShapes から選べます。Collision PresetsはNoCollision、Simulate Physicsはオフにします。
次の変数を作り、Compileして既定値を設定します。Instance Editableはオフのままにします。
| 変数 | 型 | 既定値 | 意味 |
|---|---|---|---|
| Health | Float | 100 | 現在のHP |
| BaseDamage | Float | 20 | 倍率を掛ける前のダメージ |
| DamageMultiplier | Float | 0 | ダメージ倍率。わざと入れる不具合 |
倍率 は、元の量を何倍にするかを表します。1なら20ダメージのまま、0.5なら10、0なら0です。今回は「通常の攻撃なので1であるはずなのに、0だった」という設定ミスを調べます。
② 計算するFunctionを作る
Function CalcPracticeDamage を作り、白い実行線で呼べるようにPureはオフにします。Outputsへ Damage をFloatで追加します。関数内のLocal Variablesへ CalculatedDamage をFloatで作り、既定値を0にします。
CalculatedDamageは、計算結果を一度置く この関数だけの一時変数 です。値を保存する処理の前後で止められるよう、今回は途中のSetを置きます。
- 関数の入口の白線をSet CalculatedDamageへつなぐ。
- Floatの乗算
*を置き、AへGet BaseDamage、BへGet DamageMultiplierを渡す。 - 乗算の結果をSet CalculatedDamageの値へ渡す。
- Setの白い出力をReturn Nodeへつなぎ、ReturnのDamageへGet CalculatedDamageを渡す。
Return Node は、計算した値を関数の呼び出し側へ返す出口です。この関数を呼ぶと、Damage出力から計算結果を受け取れます。

③ 呼び出した結果でHPを減らす
Event GraphへCustom Event ApplyPracticeHit を作ります。このイベントから、自作したCalcPracticeDamageを呼び、その後ろへSet Healthをつなぎます。
Set Healthに入れる値は、Floatの減算で Get Health − CalcPracticeDamageのDamage出力 にします。さらにMax(Float)へ通し、もう片方の入力を0にして、HPが0より小さくならないようにします。

図の「〜から」「〜へ」は、前後の図とのつながりを示す案内です。その名前のノードを追加するわけではありません。
Set Healthの後ろへPrint Stringを置きます。AppendのAに Health: 、BにGet HealthをTo String(Float)で変換した文字列を渡し、Return ValueをPrint StringのIn Stringへつなぎます。Durationは10秒にします。
To Stringは数値を文字へ変え、Appendはその前へ Health: をつなぎます。Printで読むのは、Setが済んだ後のHealthです。これで「呼んだ結果、HPがどうなったか」を画面でも確認できます。HP0でも敵を消す処理は入れません。

④ Fキーで同じ処理を呼べるようにする
Compile・保存し、BP_DebugDamageEnemyをPlayer Startの前へ1体置きます。ActorのScaleは1、中心は床から50cmほど上にします。Outlinerで名前を DebugEnemy に変えると、後から探しやすくなります。
- 配置したDebugEnemyを選択したまま、レベルのBlueprintメニューから「Open Level Blueprint」を開く。
- グラフで右クリックし、選択Actorへの「Create a Reference to DebugEnemy」を作る。
- その参照からApplyPracticeHitを呼ぶノードを作る。
- キーボードのFイベントを置き、PressedをApplyPracticeHitの白い入力へつなぐ。Targetは配置したDebugEnemyの参照。

Compile・保存してPlayし、ゲーム画面をクリックしてFを1回押します。Health: 100 と表示されれば、わざと作った不具合を再現できています。まずはここまで動かし、Playを停止します。
⑤ 呼び出し側で止めて、関数の中へ入る
BP_DebugDamageEnemyへ戻り、Event Graphにある CalcPracticeDamageの呼び出しノード へブレークポイントを置きます。Function一覧の名前ではなく、白線でつながったノードを右クリックします。

新しくPlayし、ゲーム画面でFを1回押します。CalcPracticeDamageで止まったら、Debug ObjectがDebugEnemyの実行中の個体を指しているか確認します。
ここではまだ、今回のDamage出力は計算されていません。Step Into で関数の中へ進み、Set CalculatedDamageを実行するところまで追います。Setの直前に止まった場合は、Step OverでそのSetを実行してください。
Getや乗算は、Setに渡す値を用意するときに評価されます。画面上の小さなノードすべてを、1個ずつステップ操作するわけではありません。
⑥ 計算に使った値を確認する
Set CalculatedDamageを実行し、Return Nodeへ進んだところで、乗算へつながっているGet BaseDamageとGet DamageMultiplierの出力ピンにマウスを乗せます。
| 見る値 | 今回確認したい結果 |
|---|---|
| BaseDamageの出力 | 20 |
| DamageMultiplierの出力 | 0 |
| 乗算の結果 | 0 |
元のダメージ20は正しく、倍率が0なので、掛けた結果も0になっています。計算ノードが壊れているのではなく、計算へ渡す設定が違う と分かります。
ここでDamageMultiplierの出力ピンを右クリックし、「Watch this value 」を選びます。Blueprint Debuggerで値を確認し、次の試行でも同じピンを見比べられるようにします。
目的の場所を通り過ぎた場合は、Return Nodeにもブレークポイントを置き、Playをやり直してFを押します。呼び出し側からResumeすると、Setが済んだReturn直前で止められます。値が出ないときは、ノードを実行済みか、対象個体が合っているかを確認してください。
⑦ 倍率を直して、同じ操作をやり直す
Playを停止します。BP_DebugDamageEnemyのDamageMultiplierの既定値を 1 に変え、Compile・保存します。ゲーム中の一時的な値だけを変えて終わらないようにしてください。
新しくPlayし、Fを1回押します。同じように関数内まで進めると、今度はBaseDamageが20、DamageMultiplierが1、乗算結果が20になります。Watchでも、評価後の倍率が1になったことを確認します。
Resumeで続け、ほかのブレークポイントでも止まったら再開します。Health: 80 と出れば、修正した計算がHPへ反映されています。
さらに倍率を0.5にして、新しいPlayでFを1回押すと、ダメージ10で Health: 90 になります。確認後は倍率を1へ戻し、不要なブレークポイントを削除または無効化します。
毎回Playを開始し直すのは、Healthを100へ戻して比べるためです。同じPlay中に続けてFを押した場合は、減った後のHPへ次のダメージが入ります。
止まらない・値が見えないとき
| 症状 | 確認するところ |
|---|---|
| Fを押しても何も出ない | ゲーム画面へ入力しているか、LevelのF Pressedと配置ActorへのTarget |
| Printは出る が止まらない | ブレークポイントの有効状態、Compile、現在のDebug Object |
| 黄色の!が出る | 印のホバー説明。純粋ノードではなく実行ノードに置けているか |
| ピンに値が表示されない | そのGetや計算を使う処理を、今回すでに実行したか |
| 倍率を1へ変えたのに0のまま | Playを止めて既定値を直したか、Compile・保存したか、別の個体を見ていないか |
おまけ:先に知っておくと良いこと
どこから呼ばれたかはCall Stackで見る
Call Stack は、「どの関数から、今の関数へ来たか」という呼び出しの履歴です。いま実行中の関数が上に並びます。よく似た入口が複数あり、どこから呼ばれたか迷うときに役立ちます。
一方、Execution Trace は、直近に実行したノードの一覧です。通ったノードを追いたいときはこちらを見ます。Blueprint Debuggerで必要な欄を開き、実行線の光り方だけに頼らず確認できます。
Accessed Noneの発生地点で止める
Accessed Noneは、相手を指していない参照を使おうとしたときなどに出るエラーです。「Editor Preferences」で Blueprint Break on Exceptions を検索し、有効にすると、こうした例外の発生地点で停止できます。ExperimentalのBlueprintsにある設定です。
止まる回数が増えるので、参照の不具合を調べたいときに使います。Component内を調べる場合は、Debug Objectでも該当Actorが持つComponentの個体を確認してください(Componentの記事)。
直した条件を、自動テストに残す
今回なら「BaseDamage20・倍率1で20が返る」「HP100へ20ダメージを与えると80になる」という条件を残せます。自動テストの記事では、こうした期待する結果をBlueprintで確かめる方法を扱います。
テストがあれば、同じ条件で不具合が戻ったときに気付きやすくなります。Debuggerで原因を調べ、テストで確認を繰り返せるようにする、と役割をつなげられます。
まとめ
Blueprint Debuggerでは、怪しい処理の直前で止め、必要な範囲だけ進みながら値を調べます。
- ブレークポイントで止まったノードは、これから実行する。
- Intoは中へ入り、Overは中を細かく追わず実行し、Outは現在の関数を終える。
- ピンやWatchは直近の実行値を見る。未実行を0だと思わない。
- Debug Objectで、ゲーム内の操作相手と観察相手をそろえる。
- 見逃したら手前で止め直し、修正後は同じ条件でもう一度試す。
ダメージの例では、20×0を20×1へ直し、最後にHP100→80まで確かめました。結果の数値だけでなく、その数値を作った材料へたどることが、原因を調べる手がかりになります。
グラフを追いにくい場合は整理の10テクニックを、よくある失敗から探したい場合はBlueprintの10のミスを参照してください。