Technology Blog

技術ブログ

2019.10.12

UE4のナビメッシュで簡単な優先順位をつける


UnrealEngine4にはいろいろと便利な機能が備わっています。
そのうちの一つが『ナビメッシュ』です。

これがあることによって、UE4におけるAI実装はかなり敷居が低くなっています。

ただ、ナビメッシュを使ったAIを実装しているとどうしてもぶち当たる壁があります。
それこそが『移動の優先順位』です。

例えば、『地点Aから地点Bに向かって人間を歩かせたい』というとき、
①直進するだけでBに着くがダメージ床だらけの道
②迂回する必要があるが安全にBに着く普通の道
の二つの選択肢がナビメッシュ上のAIに与えられた場合、
何の設定も行っていないと速攻で①のルートを選びます。

理由は簡単で、ナビメッシュ上のAIは目的地に向かって最短のルートを進もうとするからです。
ただし、これだと違和感バリバリですよね。
普通の人間が安全な道があるのに、危険な道を進みだすのはおかしいですもんね。

このような状態を防ぐための機能がUE4には最初から備わっています。
それこそが『Nav Modifier Volume』です。

『Nav Modifier Volume』を利用することによって、
簡単な移動の優先順位をつけることができます。

以下の手順で試しに設定していきます。
(1~4までは初歩的な移動AI実装なので、
優先順位について知りたいだけなら5から読み出しても大丈夫です)

ちなみに、UE4のバージョンは4.17.2、
最初のテンプレートはThirdPersonテンプレートを使用しています。
(グレイマンが使えるならなんでもいいです。後からコンテンツで追加してもOK。)

1.ナビメッシュで動かすためのキャラクターを作る

まずはブループリントを二つ作ります。
一つはAIキャラの制御に使うAIコントローラです。
コンテンツブラウザで右クリック、『ブループリント クラス』を選択し、
『AIController』を親クラスに設定して作成します。
名前はわかりやすく、『BP_AI_Controller』とでも付けておきます。
今回はこれだけでAIコントローラの実装は完了です。
中身は無くても問題ありません。

もう一つはAIで動くキャラクターです。
先ほどと同じようにブループリントの作成を行います。
今回の親クラスは『Character』を設定します。
名前はとりあえず『BP_AI_Man』とします。
作成したらAIキャラのブループリントエディタを開きます。

ノードなどの設定は不要ですが、幾つかの項目を変更します。
まずはMeshを選択し、詳細ウィンドウのMeshから、
キャラクターのスケルタルメッシュを設定します。

ThirdPersonテンプレートを選択しているなら、
最初からグレイマンのスケルタルメッシュがあるため、そちらを利用します。

また、このままでは向きがおかしいほか、浮いてしまっているため、
トランスフォームの位置を『0,0,-90』、回転を『0,0,-90』に変更します。

アニメーションの設定も一応しておきます。
Anim Classに『ThirdPerson_AnimBP』と設定すればOKです。

最後に先ほど作成したAIコントローラも設定します。
コンポーネントウィンドウで『BP_AI_Man』を選択し、
詳細ウィンドウの『AI Controller Class』を作成したAIコントローラに変更します。

これで、キャラクターとコントローラの設定は完了です。

2.マップを編集する

ThirdPersonテンプレートを選択している場合、
画像のようなマップが最初から用意されています。

3人称視点のアクションのチェックにはピッタリなマップですが、
今回のAIのテストでは邪魔なだけですので、
階段やブロックなどを消してしまいましょう。

一通り消し終えたら、今度は必要なものを配置します。

モードウィンドウから『ターゲットポイント』を選択してマップに配置します。
今回は『-500,950,130』の位置に配置しました。

続いて、モードウィンドウから『Nav Mesh Bounds Volume』を配置します。
位置は『0,0,100』サイズは『5000,5000,200』を設定します。
(とりあえずマップ全体を覆えればOK)
そして、ツールバーのビルドから『パスのビルド』を実行します。
Pキーを押して、全体が緑色に変われば問題なしです。
当然ですが、これを忘れるとAIはうんともすんともいいません。

最後に、どこでもいいのでAIで動くキャラクターを配置します。

3.レベルブループリントを編集する

グレイマンをターゲットポイントに向かって移動させる処理を実装します。

ツールバーからレベルブループリントを開き、画像のようにノードを組みます。

ちなみに、ターゲットポイントとAIキャラクターのリファレンスは
レベルで対象を選択した状態で
レベルブループリントにて右クリックを行うことで取得できます。

(本当ならビヘイビアツリーを利用するところですが、
今回の目的はただ移動させるだけなのでこの方法を使います)

試しにプレイしてみて、
AIキャラクターがターゲットポイントに向かって移動すればOKです。

4.2つのポイントを交互に移動するように設定する

先ほどまでの要領で、もう一つターゲットポイントを作成し、
以下のようにノードを組みます。

色々と問題がある組み方ですが、とりあえず動かす分には問題ありません。
なお、二つ目のターゲットポイントの位置は
『-500,-950,130』を設定しています。

プレイさせてみると、AIキャラクターが
二つのポイント間を交互に移動するようになるはずです。

5.壁を作る

さて、ここからが本題の優先順位の話になります。
先ほど作った2ポイント間移動のマップにいくつかキューブを追加し、
画像のようなマップにしてみました。

この状態でのAIの移動ルートは大きく分けて3つになります。
左、右、中央ですね。

この状態でプレイすると、もちろんAIは最短である中央のルートを進みます。
ですが、何らかの理由で左か右のどちらかを進ませたいという場合もあるでしょう。

ということで、ここで登場するのが冒頭で軽く名前を出した『Nav Modifier Volume』になります。

『Nav Modifier Volume』は通常のナビメッシュと同じようにモードウィンドウから作成でき、
詳細ウィンドウのAreaClassを変更することで、
AIから見たエリアの優先順位を他よりも下げることができます。

例えば、中央のルートを『NavArea_Obstacle』に設定してプレイを始めると
中央のルートの優先順位が下がり、AIは左か右に迂回するようになります。

もしも、全てのルートが『NavArea_Obstacle』に設定されている場合は、
AIは通常通り中央の最短ルートを通ろうとします。

NavArea_Obstacleは『移動することが可能だが他より優先度が低い』ということになります。

『Nav Modifier Volume』にはこれ以外に、
優先度が通常のままである『NavArea_Default』
ナビメッシュ自体を無効化する『NavArea_Null』
絶対に移動できない『NavArea_LowHeight』
という種類があります。

(NullとLowHeightの違いはよくわかりません。NavMeshの有無くらい?)

これを利用することによって、
AIの移動ルートの簡単な誘導くらいなら行えます。

注意点

『Nav Modifier Volume』を配置した際に
NavArea_Nullによりナビメッシュが削られ、
他のAreaClassに設定しても削られたまま、
パスビルトをしてもそのままということがよく起こります。

そのような時には『Nav Modifier Volume』のAreaClassを変更してから
エディタの再起動をしてビルドをすると、正常にナビメッシュが表示されます。

おまけ

『Nav Modifier Volume』は『Nav Modifier Component』として
アクタなどにアタッチさせることも可能です。
これにより、AIが自主的に避ける障害物などの実装も容易にできます。
(ただし、動的なナビメッシュ更新をONにする必要があります)

冒頭でも紹介した通り、この方法でできるのはあくまで簡易的な誘導のみです。
より詳細な移動ルートの設定を行いたい場合は、
個別に移動可能エリアを設定できるSupportAgentの利用がほぼほぼ必須になると思います。

また、いつかそれについても記事が書けるときが来ればいいかなと思います。

それでは、ありがとうございました。


関連ブログ