情報は力ではない

UE4 とか Blender とか。

UE4 で自動テストを試してみる。

この記事は Unreal Engine 4 (UE4) Advent Calendar 2018 の19日目の記事です。
昨日は、@AziO さんの UE4のバグ報告をして修正してもらおう! でした。

今回は UE4 の自動テストをやってみようと思います。やり方の手順は公式のドキュメントが詳しいです。
Unreal Engine | 自動化システムの概要

他にも色々な方が記事を上げてくださっています。例えば次のようなものがあります。
[UE4] コマンドから自動テストを実行してみる|株式会社ヒストリア
[ #UE4 ]Blueprintでユニットテスト・機能テスト - Qiita

今回は自動テストの実行と作成方法を見たあとに、簡単な AI に対するテストをやってみたいと思います。

テストの実行方法

自動テストはプラグインなので、Plugin を有効にし、エディタを再起動をする必要があります。

f:id:masahiro8080:20181218004219p:plain

再起動が終わったら Window から Test Automation を選択し、Session Frontend を開きます。 Automation タブのチェックボックスにチェック入れ、Start Tests ボタンを押すとテストが開始します。

f:id:masahiro8080:20181218004328p:plain

テストの結果は Automation タブで確認できます。 緑になっていたらそのテストは成功。赤は失敗を意味します。またオレンジ色のものは、警告を表しています。

f:id:masahiro8080:20181218004350p:plain

テストの実行方法がわかったので、次に自分でテストを作成して、そのテストを実行していきたいと思います。

テストの実装方法

テストは C++ でもブループリントでも実装できますが、今回はブループリントで実装していきます。

まず、FunctionalTest クラスのブループリントを作成します。ブループリントの名前は BP_FirstTest としました。

f:id:masahiro8080:20181218004408p:plain

次に、Evnet Graph タブで次のように最初のテストを書いてみました。

f:id:masahiro8080:20181218004437p:plain

Start Test イベントノードはテスト実行時に呼ばれるイベントです。 Finish Test ノードは、テスト結果を設定します。テスト結果を Test Result ピンに、テスト終了時にログに残したいメッセージをMessage ピンに設定します。

今回作ったテストは無条件にテストが成功するテストです。
テストを作成したので、作成したテストをテスト用のマップに配置します。

f:id:masahiro8080:20181218004504p:plain

再び Session Frontend を開き、Automation タブの Project から作成したテスト (BP_FirstTest) にチェックを入れ、Start Tests を実行します。 作成したテストが表示されていない場合は Refresh Tests ボタンを押すと表示されると思います。

Start Tests を押すと、Standalone のプレビュー画面が開くと思いますが一旦閉じて、Session Frontend の画面を開き、テスト結果を見るとテストが成功していることが確認できると思います。

f:id:masahiro8080:20181218004423p:plain

ここまでで、テストの作成、実行が出来るようになったかと思います。
自動テストの基本は以上です。以下は、簡単な AI に対してテストを実践してみようと思います。

簡単な AI のテスト

今回は AI の一つの動作をテストを作成しながら、実装していきたいと思います。

作成する AI について

ここで作成する AI の処理は、次のようなものです。

  • 視界内のプレイヤーの位置まで移動する

視界の距離等を決めていない雑な仕様ですが、この処理を行う AI をテストと一緒に作っていきたいと思います。

テストの作成と実行

AI とテストの実装を行う前に、プレイヤーとテスト対象の敵のブループリントを準備します。名前はそれぞれ BP_Player、BP_Enemy としました。 中身は両方とも Character ブループリントの Skeltal Mesh に SK_Mannequin を設定したものになっています。
しかし、それだけだとマップに配置した際に、どっちがプレイヤーなのか敵なのかわかりづらくなるため、頭上にテキストで印をつけています。

下の画像はテスト対象の敵のブループリントです。同じ感じでプレイヤーのブループリントも作成しています。

f:id:masahiro8080:20181218005833p:plain

プレイヤーとテスト対象の敵を準備したので、次に新しくテストを作成していきます。 名前は BP_MoveToEnemyTest として作成します。

まず、変数からです。 マップに配置したテスト対象の敵とプレイヤーをテストで使用したいので、BP_Enemy 型の変数と BP_Player 型の変数を作成しています。

変数

変数名
TargetAI BP_Enemy
Player BP_Player

次にイベントグラフです。 テストの内容としては、テスト開始一定時間後にプレイヤー(Player)とテスト対象の敵(TargetAI)の距離がしきい値以下であるかどうかを確認するようなテストにしています。

イベントグラフ

f:id:masahiro8080:20181218005547p:plain

今回のテスト用にマップ MoveToPlayerTestMap を作成し、 BP_MoveToPlayerTest を配置します。

マップにプレイヤーとテスト対象の敵を配置します。テスト対象の敵の視界内にプレイヤーが入るように配置します。 また、BP_MoveToPlayerTest の TargetAI、Player にマップ上の BP_Enemy、BP_Player をそれぞれ設定しておきます。
今回はビヘイビアツリーの MoveTo を使用するので、Nav Mesh Bounds Volume もマップに配置しておきます。

f:id:masahiro8080:20181218011017p:plain

ここまで出来たら、一度テストを実行してみます。
もちろん、ただ単に Character をマップに配置しただけで、何も実装していないのでテストは失敗するはずです。

f:id:masahiro8080:20181218011523p:plain

期待通り、テストが失敗しました。
次にテストが成功するように AI を実装していきます。

AI の実装

ビヘイビアツリー (BT_Enemy) とブラックボード (BB_Enemy) を用意し、次のように実装しました。
ブラックボードに設定されたプレイヤーまで MoveTo で移動するような処理にしています。

ビヘイビアツリー

f:id:masahiro8080:20181218231251p:plain

ブラックボード

f:id:masahiro8080:20181218231302p:plain

次に敵用の AIController (BP_EnemyAIController) を作成し、AIPerception をコンポーネントに追加します。

f:id:masahiro8080:20181218231440p:plain

AIPerception に視界の設定をします。値については初期値のままです。

f:id:masahiro8080:20181218233420p:plain

BP_EnemyAIController のイベントグラフは次のようにしました。
BeginPlay イベントでは、作成したビヘイビアツリーとブラックボードを使用する設定をしています。 OnPerceptionUpdated イベントでは、BP_Player が視界内にいるかどうかを確認して、視界内にいればブラックボードに Player を設定しています。

f:id:masahiro8080:20181218231517p:plain f:id:masahiro8080:20181218233505p:plain

最後に BP_Enemy の AIController に BP_EnemyAIController を設定します。

テストの再実行

ここまで実装が出来たら、もう一度テストを実行してみます。

f:id:masahiro8080:20181218233309p:plain

テストの成功が確認できました。
これで敵がプレイヤーの位置まで移動することが確認できました。

もう一つだけテストを追加

ここで、視界外のプレイヤーは追わないのかどうかが気になったので、次のようなテストを作成しました。
先ほどのテストとほぼ同じですが、変数にテスト対象の敵と初期位置に配置した Target Point を設定して、 テスト対象の敵が最初の位置から動いていないことを確認するテストにしています。

f:id:masahiro8080:20181218234253p:plain

テスト用のマップにはテスト対象の敵の背後にプレイヤーを配置してみました。

f:id:masahiro8080:20181218234423p:plain

これでテストを実行してみます。

f:id:masahiro8080:20181218234522p:plain

2件ともテストが成功したので、視界内のプレイヤーまで移動するという処理はとりあえず実装できたように思います。

さいごに

今回は自動テストのやり方を簡単に見ていきました。

今回実装したようなテストは、雑すぎてテストではないような気がしますが、テストの実装方法の雰囲気がわかれば幸いです。

個人的に自動テストは好きな機能で、テストがあることである程度安心して開発していくことが出来ます。

自分はゲーム会社で働いていないのでゲームにおけるテストというものがどういうものなのかわかっていません。

ゲーム会社、特に UE4 を使ってる会社、またサークルや個人開発者の方がどういうテストをしているのかに自分は興味があるので、テストに関する情報がたくさんあると嬉しいなと思います。

また、今回の記事で自動テストに挑戦する人が増えると幸いです。

今回は以上です。

明日は @ayumax さんの Unreal.js についての記事です!楽しみ!