UE4 / BP / AI(NPC)の実装例

UE4ではビヘイビアツリーをつかって自動で動くキャラクタAIを実装することができる。
ビヘイビアツリーを作り、AIの記憶用にブラックボードを作り、AIコントローラにそれらをセットし、自動化したいキャラクタにそのコントローラを適用すると自動で動くキャラを作ることができる。
AIを移動させるときはナビメッシュボリュームをレベルに配置する必要がある。ナビメッシュが存在しないとAIは移動できない。
以下、簡単なAIの実装例。

2点間移動のビヘイビアツリーを作る

ビヘイビアツリーは行動を記述するためのもの。
今回は単純に2点を移動するものを作ってみる。

ビヘイビアツリーの作成

新規 > AI > ビヘイビアツリー で作成できる。
f:id:hat0xAA:20190508111736j:plain


ビヘイビアツリーアセットをダブルクリックするとビヘイビアツリーエディタが開く。
f:id:hat0xAA:20190508113032j:plain
f:id:hat0xAA:20190508113037j:plain

ブラックボードの作成と設定

移動地点を記憶する必要があるのでブラックボードも作る。ブラックボードはAIで利用するための記憶領域。
「新規ブラックボード」ボタンを押せばビヘイビアツリーアセットと同じ場所に作成される。
f:id:hat0xAA:20190508113552j:plain


詳細欄のBlackboard Asset項目に作成したブラックボードのアセットを指定する。
f:id:hat0xAA:20190508114023j:plain


右上の「ブラックボード」をクリックしてブラックボードを編集するモードにする。
f:id:hat0xAA:20190508114516j:plain


新規キー > Vector で新しい記憶領域(キー)を2つ作り、p0、p1と名前をつける。
f:id:hat0xAA:20190508115018j:plain
f:id:hat0xAA:20190508115021j:plain


右上の「ビヘイビアツリー」をクリックしてビヘイビアツリーモードに戻る。

ビヘイビアツリーの記述

ツリーを組むのは右クリックメニューでノードを作成し、D&Dで接続することで行う。
右クリック>Composites>Sequence を1つ
右クリック>Task>MoveTo を2つ作り、
右クリック>Task>Wait を2つ作り、図のように接続する。接続はノードの下の領域からD&D
2つめのMoveToを選択して詳細>Blackboard>BlackboardKey で p1を選んでおく。
f:id:hat0xAA:20190508121040j:plain
f:id:hat0xAA:20190508123633j:plain

Sequenceは左から順にタスクを実行するという意味をもつコンポジットノードで、
このツリーの意味は
p0に移動し、5秒待ち、p1に移動し、5秒待つ。
という意味。
ツリーが最後まで実行されたら先頭にもどって実行がくりかえされる。

これでAI作成は終わり。

AIコントローラをセットアップする

次にAIを利用するためにAIコントローラを作成する。
新規>ブループリントクラス>すべてのクラス>AIController
を作成する。

f:id:hat0xAA:20190508121856j:plain
f:id:hat0xAA:20190508121859j:plain


作成したAIコントローラを開いてイベントグラフで図のようにグラフを作ってコンパイルする。
use Blackboardで使用するブラックボードを指定し、
Set Value as Vectorでブラックボードのp0とp1に(-200,0,0)と(200,0,0)をセット。
Run Behavior Treeでビヘイビアツリーを実行する。
f:id:hat0xAA:20190508122832j:plain


キャラクタにAIを適用する

レベルにキャラクタを配置し、詳細>Pawn>AIControllerClass に作成したAIコントローラアセットを指定する。
AutoPossessAI欄が"Placed in World"になっていることも確認しておく。
f:id:hat0xAA:20190508132512j:plain

これでキャラクタにAIが適用できた。

ナビメッシュをセットする

AIが移動経路を把握するためにはナビゲーションメッシュをレベルに配置する必要がある。
ナビメッシュが存在しないとAIは移動することができない。

ナビメッシュは
モードタブ>配置>NavMeshBoundsVolume をレベルにD&Dして配置し、移動範囲を含むようにサイズを調整する。
f:id:hat0xAA:20190508130727j:plain

表示>Navigation でナビメッシュがセットされたか視覚的に確認することができる。
緑色になっていたらそこが通行可能なナビメッシュ。乗り越えられない障害物のまわりは除外され、自動でよけて通ることができる。
表示が変化しないときはビューの視点を操作してみると更新される。
f:id:hat0xAA:20190508131715j:plainf:id:hat0xAA:20190508131719j:plain

これで準備完了。

実行してみる

実行してみると自動でキャラクタが2点間を移動することが確認できる。
最初の位置からp0へ移動し、その後p1<->p0間を往復する。
ナビメッシュを使っているので2点しか指定していなくても障害物は自動で回避してくれる。
PIEで実行中はビヘイビアツリーエディタでツリーの実行状態が可視化されるので状況を確認できる。
f:id:hat0xAA:20190508135556g:plain

簡単なAIの実装例は以上。

その他の機能

今回使用していない機能について。

ビヘイビアツリーには実行条件を指定する「デコレータ」と、ブラックボードの定期的な更新などをする「サービス」という2つの補助的な要素がある。
いずれもタスクなどのノードを右クリックするとそのノードに追加することができる。


AIコントローラのAI Perceptionコンポーネントで知覚に対するリアクションをさせることができる。AIが見たり聞いたりした場合にブラックボードを書き換えるなど。OnPerceptionUpdateイベントで処理する。


用語まとめ

ビヘイビアツリー
AIの行動を定義するツリー。コンポジット、デコレータ、タスク、サービスを使ってツリーをつくる。
デコレータ
実行の細かい制御を指定するもの。標準ではCooldown(前回から一定時間あける)、Loop(指定回数ループする)、Blackboard(キーがセットされているかどうかで実行)などがある。 
タスク
AIの行動。標準ではMoveToやPlaySoundなどが用意されている。
サービス
定期的にブラックボードの更新をする事などに使う補助的処理。
コンポジット
タスクの実行順を指定する。sequence , select , simple parallelの3つだけ。
sequence
ツリーの左から順に実行し、Failで中断する。
select
左から実行し、Successで中断する。
simple parallel
メイン処理が実行している間、サブ処理を並列して実行し、メイン処理の終了でサブ処理を中断する。
ブラックボード
AIの記憶領域。
キー
記憶要素。1つのキーに1つの値を記憶できる。
ナビメッシュ
移動経路を自動計算するためのシステム。AIの移動に使われる。NavMeshBoundsVolume内に作成される。

Tips

  • ビヘイビアツリーは保存していなくてもPIEで実行確認可能。
  • デコレータやサービスは、タスクやコンポジットノードを右クリックすると追加できる。
  • デコレータ、タスク、サービスともに自分で作る事ができる。ビヘイビアツリーエディタの新規作成ボタンか、BTDecorator_BlueprintBaseなどのBPクラスを作成することで作れる。
  • デコレータは関数PerformConditionCheckをオーバーライドすることで独自の条件処理を記述できる。
  • タスクはReceiveExecuteイベントで処理を書き、最後にFinishExecuteノードでSuccessかどうかを返す。
  • サービスはReceiveTickAIイベントで処理する。
  • サービスはノード選択して詳細欄でTick間隔を指定できる。サービスのBPのクラスデフォルトでも指定可能。
  • コンポジットにつけたサービスはそのコンポジットが実行経路になるとコンポジットの最初の処理でReceiveSearchStartイベントが発生し、Activeになる。経路が外れるとDeactiveになる。
  • タスクにつけたサービスの有効範囲はコンポジットごと。他のコンポジットに実行が移動したときサービスはDeactiveで終了する。なのでRootからコンポジット1つだけでループする場合サービスが多重登録されてしまうので要注意。多重実行された場合はTick間隔はだいたい等間隔になる(400ms4つならだいたい100ms。ただReceiveTickAIイベントのDeltaは400msのまま) Root-Sequence-Sequence-TaskのようにRootからコンポジット2つ経由している場合はループの時に別コンポジットを経由するので多重登録はおきない。コンポジットにつけたサービスの場合は多重登録されない。
  • MoveToタスクではVectorの他にObjectタイプも使えるがActorクラスにしないと選択できない。Objectタイプのキータイプ項目の折りたたみ部分でクラスの指定ができる。
  • MoveToタスクは目的値に到達するまで実行が継続される。Actorを指定した場合は追従する。詳細でどのくらいの距離まで近づくかなどが指定できる。
  • タスクのBPのAI MoveToノードは目的地を指定して向かわせるが、ノード自体の実行はすぐにおわる。OnSuccess実行ピンを使えば目的に到着するまで待つことができるがActorを指定していても追従しない。Actorに追従するにはループ実行してAI MoveToを繰り返し実行させる必要がある。
  • ビヘイビアツリーの各ノードの太文字部分は詳細>Description>NodeName で書き換えできる。2行目以降の小さい文字が実際のノード種類。
  • ビヘイビアツリーエディタの新規作成ボタンで作ったアセットはビヘイビアツリーと同じ場所に作成される。

公式ドキュメント

Unreal Engine | ビヘイビアツリー