Let's Enjoy Unreal Engine

Unreal Engineを使って遊んでみましょう

UE4 AIで使う移動と停止のまとめ

UE4にはAIを移動させるための機能が沢山あります。

ちょっと多すぎて、いつも移動はできるのに、どれで停止させられるのかわかりづらいですね…
個人的な備忘録も兼ねてまとめておきたいと思います。

まずUE4でAIに移動で使うための機能は大きく2種類あります。

・ブループリントで利用するMoveTo系
・ビヘイビアツリーで利用するMoveTo系

大きく分けると、この2種類ですが、それぞれに色々なノードがあります。

これらの移動系ノードと停止系ノードについて解説していきましょう。
ちなみにビヘイビアツリーの場合には、移動はビヘイビアツリーで行いますが、停止は全てブループリント上で行いますので注意してください。

移動する前の話


まず前提としてキャラクターを移動させるには、"Character Movement Component"もしくは"Floating Pawn Movement Component"のどちらかが必要となります。前者は人型キャラクターを移動させるための非常に多彩な機能を持ち、後者はベクトルを与えるだけで移動するシンプルな移動機能をポーンに提供します。

どちらも共通でナビゲーションメッシュの機能を使うことができ、Characterクラスほど強力な機能が必要ない場合には、Pawnクラスを作成しFloating Pawn Movement Componentを持たせることでAIにナビゲーション機能をもたせることが可能です。

以下で使うMoveTo系の機能を使う場合にはこれらのどちらかのコンポーネントが必要となります。

ブループリントでのMoveTo その1(Simple Move to系)


まずは最もシンプルな"Simple Move to"系です。

f:id:alwei:20170613222714p:plain
これらのノードは"Controller"と位置、もしくはActorを与えてあげるだけで簡単に移動させることが可能です。移動後はゴールに辿りつけるか関係なく、その後にコールバックイベントが発生するといったこともありません。

単純に移動したいという目的のみで利用します。

ブループリントでのMoveTo その2(AI MoveTo系)


次は"AI MoveTo"系です。系と言いつつ一種類しかありません。

f:id:alwei:20170613224135p:plain
AI MoveToの特徴はControllerを必要とせず(ただ内部的に引数であるPawnがAIControllerを持っていることが必須)、到達半径等ある程度細かい設定を行うことが可能です。

位置、もしくは対象Actorを渡すだけで移動します。
移動開始後すぐに一番上のピンが実行され、目的地に到達すると"On Success"、到達できないことが確定すると"On Fail"がそれぞれ返ってきます。
"Movement Result"にはそれぞれコールバックイベントが来た時点での移動状況が返ってきます。

ノード右上に時計アイコンがあるので、遅延(Latent)ノードとして実行されてバックグラウンドでも処理が行われます。

ブループリントでのMoveTo その3(Move To系)


"Move To"系という最もシンプルな名前がつけられているノードたちです。

f:id:alwei:20170613225652p:plain
基本的には"Simple Move to"系の強化版と考えてもらって問題ありません。AIControllerを渡して、位置もしくは対象Actorを渡すと移動します。

到達半径の設定や他にも色々と設定可能ですが、最大の特徴は"Use Pathfinding"のチェックを外すと、なんとナビゲーションメッシュがなくても移動を開始します。

ただしナビゲーションメッシュを利用しない場合にはダイレクトにゴールへと向かうので、壁や崖、落とし穴などの判断を行えないことに注意してください。

CharacterMovement利用時には、"Land Movement Mode"を"Flying"に切り替えて、"Gravity Scale"を0に設定するとなんと空中だろうと移動可能です。
空を飛び回るAIを作成する際にはとても役立ちます。

ただしこれらのノードはコールバックイベントはなく、実行後に移動が開始できたかのReturn値のみを返すというところが"AI MoveTo"との違いです。

最後にもうひとつノードを紹介します。

f:id:alwei:20170613230549p:plain
Move To系でありながら、これまで紹介してきた全てのMove Toノードの機能を内包しているのがこの"Move To Location or Actor"です。
AIControllerを渡して、位置か対象Actorを渡すと移動を開始します。
"Use Pathfinding"を外すとナビメッシュなしで移動でき、"AI MoveTo"のようにコールバックイベントが返ってきます。

基本的にこのノードさえあれば全てやりたいことが可能なはずです。というくらいにかなり万能なノードです。
AI用の移動やビヘイビアツリーでタスク内部で移動させる時に使っていきたいところ。

ビヘイビアツリーでのMoveTo

ビヘイビアツリーでのMoveTo系のノードは2種類あります。

f:id:alwei:20170614002720p:plain
"MoveTo"と"MoveDirectlyToward"の種類ですが、これらの違いはナビゲーションメッシュを利用するか、しないかというだけです。

"MoveTo"はナビゲーションメッシュを使って経路探索しますし、"MoveDirectlyToward"はナビゲーションなしでも動きますが、経路探索はありません。ブラックボードから入力された位置からActorの元へと移動する非常にシンプルなものとなっています。

移動地点に達するとタスクは成功を返し、到達できないと判断した場合はタスクが失敗を返します。"MoveDirectlyToward"の場合、最低でも5秒程度移動ができない状態が続くと失敗を返すようになっているようです。

MoveToの停止


これらの移動ノードを使った場合には、まず3種類の停止(Stop)系ノードがあります。

f:id:alwei:20170614003728p:plain
この3種類のうち2種類のノードはCharacterMovementかFloatingPawnMovementのどちらかのコンポーネントをターゲットとして必要とします。

"Stop Movement Immediately"は移動を即座に停止させるノードです。厳密に言えば、速度をゼロに設定してしまうので、移動ができなくなります。このノードだけ、ナビゲーション情報がないコンポーネントにも適用可能なので、例えば"Projectile Movement"や"Interp to Movement"コンポーネントにも適用が可能です。

次に"Stop Active Movement"です。これも上記とほぼ同じで、速度をゼロに設定します。違いはCharacterMovementかFloatingPawnMovementが必要というところくらいしかないようです。基本的にはこれでも止まります。

最後に"Stop Movement Keep Pathing"です。こいつがトラップです。止まりません。いや、厳密には速度が0になるので、一時的にストップしますが、MoveToを使っている場合は一瞬だけ止まった後に再度加速を始めて移動を開始します。一番使い道がなさそうな気がします。

ターゲットがMovement系に対しての場合はこれで全てです。

f:id:alwei:20170614004436p:plain
最後に"Stop Movement"です。これはターゲットがControllerになっているくらいでほとんど上記と同じですが、速度をゼロにするわけではなさそうです。とは言えやっていることはほぼ同じなのでもうこれでいいような気がします。

ビヘイビアツリーでの停止時の注意点


ビヘイビアツリーを使ったときに移動すると、上記のノードを使っても停止しないことがあります。厳密には停止しているのですが、それにうまく気づいていないことがあります。

例えば以下のようなビヘイビアツリーを組むと、Stop Movementさせても動きが止まりません。

f:id:alwei:20170614005250p:plain
一体なぜか?Move Toが失敗することにより、すぐ上のSequenceに戻ってしまってからすぐに再度次のMove Toを呼び出してしまうからです。この場合ちゃんと失敗した時と成功した時にWaitをさせたい場合には、間にSelectorを挟むなどの工夫が必要です。

f:id:alwei:20170614005627p:plain
これでうまくいきます。ビヘイビアツリー初心者がハマりやすい罠だと思います。今でも自分がたまにハマることがあるくらいに…

ビヘイビアツリーでAIの動きを止める際にはこれらの点に十分ご注意ください。

おまけ追記 ビヘイビアツリーのロジックの停止と再スタート


移動の停止ではありませんが、ビヘイビアツリーであればロジックの動作を停止させ、移動自体を止めておくことが可能です。

f:id:alwei:20170614102619p:plain
"Stop Logic"ノードはビヘイビアツリーの実行を完全に止めます。停止後に再スタートしたい場合には"Restart Logic"を呼び出してください。結果的にこれでMoveToも止めておくことができます。

ビヘイビアツリー自体が停止するので、外部のブループリントから呼び出す必要があります(AIControllerあたりでやるのがベスト)。

なお"Get AIController"の純粋関数版はUE4.16で追加されたものです。4.15以前だと非純粋関数版しか存在しないので注意してください。
"Brain Component"はロジックを一時停止する際に使われるための小さなコンポーネントです。