ダメージ計算を直すたびに、ゲームを再生して敵を攻撃し、HPの減り方を確認する。会心や防御力の処理も増えてくると、以前は動いていた攻撃まで確かめ直すのが大変になります。
こうした確認を、同じ手順で何度でも繰り返せるようにするのが 自動テスト です。この記事では、UEの Functional Test を使い、「20ダメージを与えると、HPが100から80に減る」ことをBlueprintで確かめます。
この記事でわかること
- いつもの目視確認と自動テストの違い
- Functional Testの役割と、最初のテストの作り方
- 敵のHPを比べ、成功・失敗を判定するノードのつなぎ方
- わざと不具合を入れて、テストが見つけられるか確かめる方法
いつもの動作確認を、テストとして残す
普段は Print String でHPを表示し、「80になったから大丈夫」と確認していると思います。自動テストでは、この 値を見て判断するところまで をBlueprintに任せます。

例えば、次の3つを順に実行するテストを作ります。
- HP100の敵を用意する。
- その敵に20ダメージを与える。
- HPが80になっていれば成功、それ以外なら失敗と記録する。
これを残しておけば、後から会心の処理を追加したときも、テストを実行するだけで「普通の攻撃では20減る」という動きを確認し直せます。一度きりの動作確認が、次の変更でも使えるようになります。
ゲームのどこをテストする?
最初は、条件と答えをはっきり決められるものが向いています。

- RPG:20ダメージを受けたら、HPが100から80に減る。
- パズル:同じ宝石が横に3個並んだら消え、2個なら消えない。
- アドベンチャー:宝箱を開けてセーブしたら、ロード後も開いたままになっている。
全部を一度にテストする必要はありません。何度も確認している処理や、以前にバグが出た条件を1つ選ぶと、作る意味を実感しやすいです。
Functional Testは、動作を確かめるためのActor
Actor(アクター) は、敵やライトのように、レベルへ配置できるものの基本となる種類です。レベル は、それらを並べてゲームの場面を作る場所です。
Functional Test は、テストを始めたり、結果を記録したりする機能を持つActorです。これをもとにBlueprintを作り、「敵を用意して、ダメージを与え、HPを調べる」という手順を組みます。
敵のBlueprintとは別に作るので、まずは2つの役割を分けて考えましょう。

BP_Enemy:ダメージを受けたら、自分のHPを減らす。普段のゲームで使う処理です。BP_Test_Damage:敵の処理を呼び出し、その後のHPを確かめる。こちらがテストです。
大切なのは、テストから 実際のゲームの処理を呼ぶ ことです。テスト側でHPを直接80に書き換えたのでは、ダメージ処理が動かなくても成功してしまいます。HPを減らすのは敵に任せ、テストはその結果を読み取ります。
Functional TestにはC++で拡張する方法もありますが、ここで作るテストはBlueprintだけで組めます。
まずは、開始して終了するテストを作る
最初からHPの判定まで組まず、まずは「テストを実行して、成功と表示される」ところまで進めます。先にここを通しておくと、後から失敗したときに、テストの準備とダメージ処理を分けて調べられます。

1. テスト用のレベルを用意する
「編集(Edit)→ プラグイン(Plugins)」で Functional Testing Editor を検索し、有効にします。再起動を求められたら、エディタを再起動してください。
次に、床とライトだけの小さなレベルを作り、L_Test_Damage という名前で保存します。他の敵やゲーム進行に邪魔されず、同じ条件で試せる場所にします。
2. テスト用Blueprintを作り、配置する
コンテンツブラウザで「Blueprint Class」を作成 し、「すべてのクラス(All Classes)」から Functional Test を検索します。親クラスに選び、名前を BP_Test_Damage にしてください。親クラス は、新しいBlueprintがどの機能を引き継ぐかを決める土台です。ここでFunctional Testを選ぶと、テストの開始・終了機能を使えるようになります。
作成したBlueprintをテスト用レベルへ1体置き、レベルを保存します。アセットを作るだけでなく、実行するレベルに配置するところまで が準備です。
3. 開始から終了へつなぐ
BP_Test_Damage を開き、イベントグラフに Event Start Test と Finish Test を置きます。イベントグラフは、処理を表す ノード を並べ、線でつなぐ編集画面です。
ノードの接続口を ピン と呼びます。白い矢印形の 実行ピン をつなぐと、「どの処理の次に、どの処理を動かすか」が決まります。Event Start Test の実行出力から Finish Test の実行入力へつなぎ、Test Result を Succeeded にしてください。
Event Start Test → Finish Test(Test Result = Succeeded)
- Event Start Test:テストを実行したときの入口です。
- Finish Test:テストを終了し、結果を伝えます。
Succeededは成功、Failedは失敗です。
検証の処理は、普段の Event BeginPlay ではなく Event Start Test から始めます。この後、2つのノードの間へHPを確かめる処理を入れていきます。
補足:終了しないテストを見つける
配置したテストActorの「Details」で
Time Limitを5.0秒、Times Up ResultをFailedにしておきます。終了処理のつなぎ忘れがあっても、待ち続けずに失敗として確認できます。
Session Frontendで実行する
Session Frontend は、テストを選んで実行し、結果を確認する画面です。Blueprintをコンパイルし、レベルを保存してから開きます。

- 「ツール(Tools)→ Test Automation」を開きます。バージョンによっては「Session Frontend」から「Automation」タブを開きます。
- 実行対象に、現在開いているエディタのセッションを選びます。セッションは、テストを動かすエディタやゲームの起動単位です。ここでは自分が作業中のエディタを指定します。
- 一覧の
Project配下から、テスト用レベルや配置したテストの名前を探してチェックを入れます。 - 「Start Tests」を押します。
テストが完了し、成功と表示されれば準備完了です。今は開始と終了をつないだだけなので、HPの確認はこれからです。
一覧に見つからない場合は、テストActorを配置してレベルを保存したかを確認してください。プラグイン、選択中のセッション、検索フィルターも確認候補です。図は操作の概略で、表示名や階層はUEのバージョンによって異なります。
Assertは「この結果になるはず」の確認
HPが80になったかどうかを調べるには、Assert(アサート) というノードを使います。「実際の結果」と「こうなるはずの結果」を比べるためのものです。
この「こうなるはずの結果」を 期待値 と呼びます。今回なら、100から20を引いた 80 が期待値です。

今回のHPは、Float(小数も扱える数値の型) で作ります。値の型に合わせて Assert Equal (Float) を使い、次の2つを渡します。
- Actual:ダメージを受けた後、敵から読み取ったHP。
- Expected:期待値。この例では
80.0。
ほかにも、スコアのような整数には Assert Equal (Integer)、扉が開いたかなどの条件には Assert True が使えます。まずは今回のFloatの比較を1つ使えれば十分です。
「比べる」と「終わる」を分けて考える
Return Value(戻り値) は、そのノードが処理の結果として返す値です。Assertの場合は、比較 が通ったことを表す true か、通らなかったことを表す false が返ります。この「はい/いいえ」の2通りを持つ型が Boolean(Bool) です。
Branch は、条件がtrueかfalseかによって、次に進む処理を分けるノードです。Assertの戻り値をBranchの Condition(条件)へ渡し、trueなら成功、falseなら失敗として Finish Test へ進めます。
Assertで確かめ、Finish Testで終わる という流れです。実践では、このつなぎ方も図で確認します。
実践:20ダメージでHPが100から80になるか確かめる
ここから、敵とテストを実際につなぎます。完成すると、敵にダメージを与え、HPが80なら成功と表示されます。HPを減らす処理を外すと、同じテストが失敗に変わります。

1. ダメージでHPが減る敵を用意する
まずは確認される側の BP_Enemy です。既に ダメージ処理の記事 の敵があれば、同じ役割の変数と処理を使えます。初めて作る場合は、親クラスを Actor にして、次の変数を追加してください。
| 変数 | 型 | 初期値 |
|---|---|---|
CurrentHealth | Float | 100.0 |
「Class Defaults」で Can Be Damaged を有効にします。今回は単独実行で試し、AIや自動回復など、別の場所でHPが変わる処理は加えません。
この敵は、HPの変数とダメージ処理だけでも作れます。見た目の部品は付けないため画面には映りませんが、生成した敵のHPはテストから読み取れます。
イベントグラフには、次の接続を作ります。Event AnyDamage が受け取ったダメージを、現在のHPから引いて書き戻します。接続図は見やすい配色と配置に整理しているので、エディタではノード名・ピン名を合わせてつないでください。

Event AnyDamageとSet CurrentHealthの実行ピンをつなぎます。- Floatの減算ノードの
AにCurrentHealth、BにDamageを渡します。順番は 現在のHP − ダメージ です。 - 減算の結果を
Set CurrentHealthの値へつなぎます。
後でテスト側から使う Apply Damage は、敵へダメージを知らせるノードです。HPの変数を自動で書き換えるわけではないので、敵側にこの処理が必要になります。
2. テストから敵を生成し、ダメージを与える
次は BP_Test_Damage です。次の変数を追加します。
| 変数 | 型 | 値・用途 |
|---|---|---|
TestDamage | Float | 20.0。与えるダメージ |
ExpectedHealth | Float | 80.0。期待するHP |
enemy | BP_EnemyのObject Reference | 生成した敵を保存する |
enemy は、今作った敵を後から指定するための変数 です。ここに保存した敵へダメージを与え、同じ敵からHPを読み取ります。
最小構成の Finish Test への接続を外し、まずは敵を生成するところを組みます。

Spawn Actor from Classは、指定したBlueprintからActorを1体作るノードです。ClassをBP_Enemyにします。Spawn Transformは生成時の位置・向き・大きさの指定で、床や他のActorと重ならない位置にします。Return ValueをSet enemyへ渡し、生成した敵を保存します。- 実行ピンのある
Is Validで、enemyが実際に存在する敵を指しているか確認します。生成に失敗した場合などはIs Not Valid側へ進むので、Finish TestでFailedにし、Messageに「敵を生成できませんでした」と入れます。
図の Get enemy は、保存した敵を取り出すノードです。変数をグラフへドラッグし、「Get」を選んで配置します。TestDamage と ExpectedHealth も、同じように「Get」で読み取って使います。
敵を生成できたら、図の「B」から次の処理へつなぎます。「B」と「A」は図をまたぐ接続の目印で、追加するノードではありません。

Register Auto Destroy ActorのActorにenemyを渡します。テストが終わったら、この敵を自動で片付けるための設定です。Target(この機能を呼び出す相手)はSelfのままにします。ここでのSelfは、処理を書いているBP_Test_Damage自身です。Apply DamageのDamaged Actorにenemy、Base DamageにTestDamageを渡します。攻撃者に関する入力は、この例では使わないので未接続で構いません。- 「A」の先を、次の節のHP判定へつなぎます。
毎回新しい敵を作るのは、必ずHP100から確かめるため です。前のテストでHPが80になった敵を使うと、次は60になり、ダメージ処理が正しくても失敗してしまいます。
3. HPを比べて、テストを終了する
Apply Damage の後に Assert Equal (Float) をつなぎます。Get enemy の出力からドラッグして Get CurrentHealth を検索すると、その敵のHPを読むノードを置けます。読み取った値を Actual へ渡してください。

| ピン | 渡す値 |
|---|---|
Target | Self(このテスト自身) |
Actual | enemy の CurrentHealth |
Expected | ExpectedHealth(80.0) |
What | 「ダメージ適用後のHP」 |
Tolerance | 0.01 |
What は、何を確かめたかが分かる名前です。失敗したときの記録に出るので、「テスト1」より「ダメージ適用後のHP」のように書くと調べやすくなります。
Tolerance は、小数の計算で生じるわずかな誤差をどこまで許すかの設定です。今回は 0.01 にします。HPが80と100では、この範囲を大きく超えるので失敗します。
最後は、Assertの実行出力を Branch へ、Return Value を Condition へつなぎます。True 側は Finish Test → Succeeded、False 側は Finish Test → Failed です。
図では、処理を進める線と値を渡す線を分けて示しています。Get CurrentHealth は値を読むだけなので、実行ピンはありません。AssertへHPの値を渡す線をつないでください。
4. わざと失敗させてから、元に戻す
コンパイル・保存して実行し、成功することを確かめます。次は、HPが減らなかったときに見つけられるか を試します。
BP_Enemyの減算を、一時的にCurrentHealth − DamageからCurrentHealth − 0に変えます。- コンパイル・保存し、同じテストを実行します。
- 失敗した結果の詳細を開き、「ダメージ適用後のHP」を探します。期待値は80、実際の値は100になっているはずです。
- 減算を
CurrentHealth − Damageに戻し、もう一度実行します。成功に戻れば確認完了です。
この間、期待値の80は変えません。「本来は80になるはず」という基準を残しておくからこそ、HPが減らない不具合を見つけられます。
ここまでできたら、今度は TestDamage を 35.0 に変えてみてください。期待値が80のままなら失敗し、ExpectedHealth を 65.0 にすれば成功します。与える値と期待する結果を組にする と、別の攻撃でも同じ形でテストを作れます。試し終えたら、今回の設定である20と80へ戻しておきましょう。
ポイントは2つです。
- 毎回、同じ条件から始める:前回のHPや残った敵に、結果を左右されないようにします。
- 成功だけでなく失敗も確かめる:不具合を入れても成功するな ら、確認したい処理や値につながっていません。
うまく動かないときは
まず、テストを実行できていないのか、実行した結果が期待と違うのかを分けます。
| 症状 | 確認するところ |
|---|---|
| 一覧にテストが出ない | テストActorの配置とレベルの保存、プラグイン、セッション、検索フィルター |
| 終了しない・時間切れになる | 成功・失敗のどちらの経路も Finish Test へつながっているか |
| 敵を生成できない | Class と Spawn Transform、生成位置で他の物に重なっていないか |
| HPが100のまま | Can Be Damaged が有効か。敵側で減算し、Set CurrentHealth へ書き戻しているか |
| HPを減らさなくても成功する | Assertの実行線、Actual に渡す値、Return Value からBranchへの接続 |
値を追いたいときは、Blueprint Debugger で Event AnyDamage に止めてみると、ダメージが届いたか、どのHPを書き換えたかを確認できます。
おまけ:先に知っておくと良いこと
不具合を直したら、その条件を残す
例えば「無敵中なのにダメージを受ける」というバグを直したなら、無敵中の敵へ攻撃し、HPが変わらないことを確かめるテストが役立ちます。同じ不具合が後の変更で戻っても、見つける手がかりになります。
最初から大量に作るより、繰り返し確認したい条件が増えたら、テストも1つ増やす くらいから始めると続けやすいです。
結果が出るタイミングに合わせて確かめる
今回の敵は、ダメージを受けるとその場でHPを更新します。そのため、Apply Damage の直後にHPを比べられます。
一方、ドアが開き終わったかを調べるなら、開く処理を呼んだ直後では早すぎます。アニメーションの完了など、結果が出るタイミングを待ってから確かめます。「処理を呼べた」と「動き終わった」は分けて考えてください。
数値の確認と、遊んで確かめる時間を両方持つ
このテストは Apply Damage を直接呼ぶので、弾が敵に当たるところは通りません。HPの計算が正しくても、攻撃の当てやすさやダメージ演出の伝わりやすさは、実際に遊んで確認します。
ダメージ処理を変更した後や、パッケージ化 の前など、テストを再実行するタイミングを決めておくと使い忘れを減らせます。
まとめ
自動テストは、いつもの動作確認を繰り返し使える形で残す仕組みです。今回の例なら、敵を用意し、20ダメージを与え、HPが80かを比べる。この3つが基本になります。
Functional Testを親にしたBlueprintを作り、レベルへ配置する。- ゲーム本体の処理を呼び、
Assertで結果を比べる。 Finish Testで終了し、成功と失敗の両方を確かめる。
あなたのゲームで、変更のたびに同じ手順で確かめていること は何でしょうか。まずは、その確認を1つ残してみてください。
参考資料
詳しい設定やノードの入出力は、Epic公式の Functional Testing、テストの実行方法、Assert Equal (Float)を参照してください。