ゲームAI
UE4
UnrealEngine

【UE4】AIを良い感じに歩かせたい

はじめに

Unreal Engine 4 (UE4) その2 Advent Calendar 2018 10日目の記事です。

Unreal Engine 4 (UE4) その2 Advent Calendar 2018

まずは結果確認

早速ですが今回の記事を参考にAIの歩行運動を良い感じにした場合と、エンジンにビルトインされているデフォルトの歩行運動機能を実行した場合との結果を提示します。

Characterブループリントでは
Use Controller Rotation Yaw = チェックを外す
Orient Rotation to Movement = チェックを入れる
Rotation Rate = Zを90に変更
と各種オプションを設定しています。
それぞれの歩行運動機能をAIControllerクラスで実装しアタッチしています。

カスタムした方は曲がり角で、非常にスムーズな経路を辿っておりとても人間的です。それと比べデフォルトの方では曲がり角をほぼ直角に曲がります。
更にデフォルトの方ではオプションを設定したことで即座に進行方向に振り向くのではなく、少しゆっくりと進行方向へと振り向きます。それによって移動方向とエージェントの体の向きが揃っておらず、いわゆるストレイフ移動(Strafing Movement、平行移動、カニ歩き)が発生しています。カスタムの方ではストレイフ移動は発生せず、移動方向とエージェントの体の向きが一致しています。

プロジェクトはこちら

バージョン:4.21.0
https://1drv.ms/u/s!Au-8FqgREBKZhTvkxVeDjmderuY9

AIC_CustomMoveTo ブループリント

結果を見ていただいた通り、カスタムとデフォルトでは大きく差異があり、デフォルトの方では不自然な点が多く見られたと思います。この問題をどのように解決したのかをプロジェクトのAIC_CustomMoveToの実装を提示しつつ紹介していきます。(これはAI Controllerクラスを継承したクラスです)

ここで提示する実装例はあくまでも理解のしやすさ、ブループリントの見通しのよさを重点に置いているので何かしらのプロジェクトで使用する場合には更に機能追加が必要になるかもしれません。

1. 目的地までの経路を見つける

2018-12-01_16h03_44.png

カスタムの歩行運動機能では用意されているAI Move Toノード等の移動ノードは使う事が出来ません。ですが「どの経路を通るべきか」という情報は必須なのでFind Path to Actor Synchronouslyノードで目的地までの経路を取得し保持しておき、現在、どの曲がり角へ向かっているかを記録するためのインデックスを初期化します。

2. 曲がり角へ到達しているかチェック

2018-12-01_16h09_58.png

現在向かっている曲がり角の座標位置を取得し、コントロール中のPawnとの距離をチェックしAcceptance Dist以内ならTRUEを返します。

3.1. Pawnの回転と移動

2018-12-01_16h21_09.png

2番でのチェックでFALSEが返った場合の処理です。ここがAIを良い感じに歩かせる肝となる箇所です。
見ての通り処理自体は非常に単純です。

Find Look at RotationノードでPawnから向かっている曲がり角へと向かう回転を取得し、RInterp Toノードへと渡します。返ってきた値をPawnの回転へセットすることで、徐々に曲がり角へ向くようになります。

次に移動です。これはプレイヤーキャラクターの操作でお馴染みのAdd Movement Inputノードを使っています。World Directionへと渡すベクトルはPawnの前方ベクトルです。

Find Look at RotationとRInterp Toにより徐々に向きを変えつつ、常に前方へと移動する。この2つを組み合わせることで、デフォルトの歩行運動機能の問題点(直角に曲がる、移動方向と体の向きの不一致)が解決します。

3.2. インデックスの更新

2018-12-01_16h38_40.png
2番でのチェックでTRUEが返った場合の処理です。
保持した経路配列のサイズと現在のインデックスを比べ、配列の最後のインデックスと現在のインデックスが同値であれば目的地へ到達したとし、TRUEを返します。そうではない場合現在のインデックスをインクリメントしてFALSEを返します。
2018-12-01_16h38_49.png

4. Tickの停止

2018-12-01_16h39_32.png

3.2番にてTRUEが返った場合はSet Actor Tick Enabledで更新を止め、移動処理を今後行わないようにしています。

Behavior Tree版

AI Controllerでの実装をそのままBehavior TreeのBTTaskへと移植したバージョンもプロジェクトに同梱してあります。アセット名はBTT_CustomMoveToです。
2018-12-05_22h07_32.png

AI Controller版と違いはほとんどありません。目的地到達後の処理がSet Actor Tick EnabledノードからStop Logicノードに置き換わっているくらいです。

BTTaskではFinish Executeノードを通してBehavior Treeシステムにタスクの成功\失敗を通知します。BTT_CustomMoveToではエージェントが最終目的地に到達した場合にのみFinish ExecuteノードでTRUEをセットし、成功を通知します。
Finish Executeノードが呼ばれない間、BTTaskノードは処理中を表すEBTNodeResult::InProgressを返します。InProgressは「今このタスクを処理中だから他のタスクには遷移しないでくれ~」という状態を表すものです。
これによりBTT_CustomMoveToはエージェントが最終目的地に到達するまで他のタスクに遷移はしないようになります。

おわりに

今回紹介した実装方法は
The Occupation で採用された AI ロコモーションのレイヤー アプローチ
を参考にしたものです。
実装例もどこかの掲示板かなにかに貼り付けられていたものをベースに書き直したものなのですが、失念してしまい探し出すことも出来ませんでした。

今回はブループリントのみでお手軽に結果を出してみましたが、より見栄えの良い歩行運動を行わせるには上記リンク先のようにアニメーションとアニメーションBPとの連携も必須となります。例えば配布したプロジェクトでは見栄えが良くなるようなレベルになっていますが、目的地をエージェントの真後ろにした場合、不自然に大回りするように見えるはずです。

このようなエージェントの歩行運動機能は一人称・三人称のシューターやアクションに登場するエージェントには不向きだと思いますが、オープンワールドによくある市民等のエージェントには非常にマッチするはずです。
機会があれば是非お試しいただければと思います。

ここまで読んでいただきありがとうございました。


明日は@diberidarshiさんの記事になります。
ARKitについてですかね?とても楽しみです!