自律的な振る舞い

モーショングラフィックスとゲームの表現における大きな違いの一つして、ゲームには敵キャラクターのような自律的に判断し移動するオブジェクトの存在があげられます。

このチュートリアルでは下記のサンプル映像のように、プレイヤーを発見したら追跡し、近づいたら攻撃する、というシンプルな振る舞いをUnreal EngineのAIコントローラーを用いて実装してみたいと思います。

私自身がまだ経験不足ということもあり、内容は高度なものを目指さず、なるべく単純になるよう心がけました。中には私なりの独自の解釈も含まれていますので、物足りない方や正しい詳細情報を知りたい、という方はぜひ公式サイトをご覧ください。

また、間違っている点や、もっと良い方法がある、といった情報もお待ちしています

 

 

なお、サンプルのキャラクターはRPG Monster Wave PBR、背景にはLow Poly Dungeon Asset Packのアセットを使用しています。

ユーザーの操作によるキャラクター

Unreal Engineにはキャラクターブループリントというブループリントクラスがあります。これはキャラクターの移動やジャンプなどの基本的な行動をしやすくするもので、テンプレートのThirdPerson Characterの内部を見てみると、操作イベントとCharacter Movementコンポーネントを組み合わせていることがわかります。

AIによる自律的なキャラクター操作

一方で自律的なキャラクターを実現するためには、ユーザー操作の代わりに「AIコントローラー」を用いてキャラクターを動かします。AIコントローラーには知覚や行動ルールを組み込むことができるビヘイビアツリーという仕組みがあるため、プレイヤーに気づいて追いかけてきたり、攻撃したりといった、状況に応じた振る舞いが可能となります。

AIコントローラー

キャラクターブループリントにAIコントローラーを設定すると、そのキャラクターの振る舞いはAIコントローラーに委ねられる事になります。AIコントローラーは大きく「行動・記憶・知覚」の3つの機能で構成されており、それらの関係性は非常に興味深く設計されています。しかし、それぞれの関係が入り組んでいるために、すんなりと理解するのは難しく、ざっくりと構成を把握するために下記のような図を作ってみました。

  1. AI Perception (知覚)
  2. ブラックボード (記憶)
  3. ビヘイビアツリー (思考)
AIに必要なコンテンツの作成

今回AIコントローラー関連で使用するコンテンツは以下の7つにです。中身は空っぽで構いませんので、最初に全て作ってしまうと作業がスムースかと思います。名前も合わせておいたほうが問題が起きにくいかもしれません。

ブラックボードの設定

BB_Enemy

ブラックボードにはビヘイビアツリー内で使用できる変数の集合体です。今回は標的となるプレイヤーを保存しておくためのObjectと、攻撃フラグを保存しておくBoolの二つを用意しました。

今回のチュートリアルでは、AI関連が使用する共通の変数をこのブラックボードに集約してみました。AIの記憶の機能をブラックボードに持たせた形になります。

  1. 追跡するアクターを保持する変数「TargetActor」
  2. Key TypeをObjectに変更
  3. Base ClassをActorに変更
  4. 攻撃モード用Bool型変数を追加「AttackFalg」
  5. 検知用Bool型変数を追加「SensedFalg」
ビヘイビアツリーの設定

BT_Enemy

まだタスクなどの詳細を作成していない状況かもしれませんが、下図のようにツリーを構成します。それぞれどのような機能を果たしているかは、ツリー内に記述したコメントを参考にしてください。またより詳しいビヘイビアツリーの解説に関しては公式ドキュメントが参考になります。

実装するルール

目標となるプレイヤーに気づいていなければ何もしない。近距離にプレイヤーがいたら攻撃モードに入る。そうでなければプレイヤーに近づく。

  1. 使用するブラックボードの指定
  2. セレクターを追加
  3. 敵に気づいているかをチェック
  4. 近距離にいたら攻撃のフラグを一定時間ON
  5. プレイヤーの情報を取得
  6. プレイヤーに向かって移動する(デフォルトのタスク)
  7. 目標地点の接近限度の半径
  8. 標的となるアクターを設定(プレイヤー)
AIコントローラーの設定 1

AIC_Enemy

ビヘイビアツリーの起動と変数の作成

AIコントローラーの基本的な役割は、ビヘイビアツリーを実行状態にし、キャラクターの状態を変数などで保持する事になると考えて良いでしょう。今回は状態を保存するための二つの変数を作成しておきます。

  1. 知覚しているかどうかのフラグ変数の作成
  2. 使用するブラックボードの指定
  3. ビヘイビアツリーの起動
AIコントローラーの設定 2

AIC_Enemy

AI Perceptionの追加と知覚の設定

AIコントローラーのもう一つの重要な役割は、AI Perceptionコンポーネントを追加して視覚や聴覚などの知覚機能を設定する事にあると思います。この設定次第によって、敵キャラクターの敏感度や記憶力など変更することが可能になります。

  1. コンポーネントからAI Perceptionを追加
  2. AI Perceptionを選択
  3. 知覚を追加
  4. 知覚のタイプを視覚「AISight_Config」に設定
  5. implementationを「AISense_Sight」に設定
  6. 全てのDetectをONにして全てを知覚できるように設定
  7. 知覚に変化があった時のイベントを作成
  8. 更新のなった知覚全てを処理
  9. 知覚の詳細を取得
  10. 知覚していることをブラックボード内の変数「SensedFlag」で保持
デコレーションの設定

BTD_Distance

敵キャラクターと標的プレイヤーが近くにいるか?を判断する。

デコレーターはビヘイビアツリー内で条件式として使用され、Trueを返す場合のみ、下部に接続されたタスクが実行されます。今回のビヘイビアツリーでは、プレイヤーと接近していた場合のみ攻撃のタスクが実行されるようになっています。

  1. 関数のオーバーライドから「Perform Condition Check AI」を追加
  2. 敵キャラクターの位置を取得
  3. プレイヤーの位置を取得
  4. 距離を計測
  5. 距離が250以下の場合にTrueを返す
サービスの設定

BTS_Target

プレイヤーの位置を継続的に参照

サービスはセレクターやシーケンサーに付加され、下流のタスクに継続的に情報提供を行う役割を持っています。今回のビヘイビアツリーでは、下流にあるMove Toにプレイヤーを連絡し続ける役割になっています。

  1. プレイヤーのアクターを取得
  2. ブラックボードの変数「TargetActor」にプレイヤーをセット
知覚用タスクの設定

BTT_Sensed

知覚の取得「プレイヤーを見つけているか?」

タスクはビヘイビアツリー内で実際に行われる行動などの処理となります。このタスクではブラックボード内の変数「SensedFlag」を取得し、AI Preceptionがプレイヤーを検知しているかどうかを判断しています。検知している場合はタスク完了時に「失敗」を返しています。

失敗を返すことでSelectorはツリーの右側の処理へと移行させますので、結果的に「気づいている場合は、近距離にいるかどうかを調べる」という流れに移行することになります。

  1. ブラックボード内の変数SensedFlagを調べる
  2. SensedFlagを反転(知覚している際に次のタスクに移行したいため)
  3. タスクの完了
攻撃用タスクの設定

BTT_Attack

一定時間、攻撃モードに入る

敵が近距離にいた場合に実行されるタスクです。ブラックボード内の変数「AttackFlag」を1秒間だけONにして、その後「成功」を返してタスクを必ず終了させています。

  1. ブラックボードの変数AttackFlagをONにする
  2. 一秒間待機する
  3. AttackFlagをOFFにする
  4. タスク完了時に必ず「成功」を返す

 

なおAttackFlagがONになると、後に説明するアニメーションブループリントが反応して、攻撃モーションが再生される仕組みになっています。

これでAI関連のセットアップは完了となります。まだキャラクターに適応していないので実感がないかもしれません。ここから実際にキャラクターをAIで制御してみましょう。

実際にAIコントローラーでキャラクターを操作

これでAIコントローラー関連のセットアップは完了しましたので、実際に使用してみましょう。動かしたいキャラクターブループリントを開き、クラスのデフォルトからAI Controller Classというパラメータを探して、作成したAIC_Enemyを設定します。

  1. クラスのデフォルトを選択
  2. AI Controller ClassにAIC_Enemyをセット
  3. Use Controller RotationをOFFに
  4. Character Movementを選択
  5. Orient Rotation MoveをONに
攻撃モーションとの連動

さらに攻撃時のモーションに対応してみます。キャラクターブループリントが使用しているアニメーションブループリントを下記のように設定してみました。ブラックボードへアクセスしているのがポイントかと思います。

イベントグラフ

  1. イベントグラフを開く
  2. 攻撃フラグ用変数「AnimBP_AttackFlag」を作成(Boolean型)
  3. AIコントローラー「AIC_Enemy」にアクセス
  4. ブラックボード内変数「AttackFlag」を取得
  5. AttackFlagの値をそのままこのアニメーションブループリント内の変数AnimBP_AttackFlagにインプット

アニムグラフとステートマシン

今回はAIコントローラーのチュートリアルということもあり、ステートマシンの細かい解説は割愛しますが、ここでのセットアップのポイントは、67になるかと思います。

変数AnimBP_AttackFlagがTrueであれば攻撃モーションを再生、Falseであれば通常モーションに戻るようにセットアップされているのですが、AnimBP_AttackFlagはブラックボード内変数AttackFlagを元にリアルタイムに更新されているので、結果的にブラックボード内の変数に同期したモーションとなっています。

  1. アニムグラフを開く
  2. ステートマシン
  3. ステートの構成
  4. 通常移動のステート内の構成
  5. 攻撃ステート内の構成(攻撃モーション再生)
  6. 攻撃モーションへの移行条件
  7. 攻撃モーション完了の条件
移動範囲の設定

これでAIコントローラーのセットアップは完了なのですが、このままではキャラクターは動きません。レベルに移動可能な領域が設定されていなければ、AIコントローラーは正しく機能しないようです。配置パネルからNavMesh Bounds Volumeを追加して、移動可能な領域全体を覆うようにスケールで拡大します。

移動可能な領域はレベルのビューポートをアクティブにしてキーボードの「p」をクリックすると、緑色にハイライト表示されます。

  1. NavMesh Bounds Volumeをレベルに追加
  2. 移動可能領域を覆うように大きさ調整
  3. ビューポート上で「p」キーで領域確認
完成

ちょっと長くなってしまいましたが、これでこのチュートリアルは完了です。無事キャラクターはプレイヤーに反応して動いたでしょうか? AIコントローラーとビヘイビアツリーによるモーションは設定する項目が多く、その関係性を把握するのが難しい印象ではあります。

しかし、それぞれのロジックが抽象的に構成され、お互いの依存度も低いので、汎用的で使い回しがきく設計になっていると感じました。

今回のチュートリアルでは聴覚もなく、見えなくなるとすぐに追跡を止めてしまうので、すぐに逃げ切れてしまいます。ぜひこの入門を一つのステップとして、皆さんならではの複雑な思考パターンや、リアリティのある振る舞いの実装にチャレンジしてみてください。ご意見、ご感想もお待ちしています。

メニュー