この記事は、「アンリアルクエスト5に挑戦!  初級・中級解説編」の続きです。初級・中級の解説を見たい方はリンクより前記事を参照してみてください。

1日目上級クエスト「ビヘイビアツリーを使って敵を賢くしよう!」

1日目初級の上級クエストは「ビヘイビアツリーを使って敵を賢くしよう!」でした。「賢く」という抽象的な指示でしたので、色いろな回答があったかと思いますが、今回はサンプルとして”敵のHPが多い時は攻撃してきて、HPが少なくなったら逃げ回る”というロジックにしてみたいと思います。

なお、分かりやすさを優先する為、アンリアルクエスト5用のプロジェクトを一旦リセットした状態(プロジェクトデータの配布状態)からの実装を前提に解説していきます。

そもそもビヘイビアツリーとは?

ビヘイビアツリーとは、簡単に言えばプレイヤー以外のキャラクター等の動きを制御する為の条件分岐とその行動を専用に記述する為の仕組みです。

プロジェクト内のUnrealQuest5/AI/BT_Enemyがその実態となります。

AIで動作するキャラクターは、一番上の「ルート」から条件毎に辿っていき、最終的なタスクノード(Move ToとかRotate to face BB entryって書いてるノードです)の行動をするようになっています。

また、ビヘイビアツリーには関連付けされたブラックボード(直訳で黒板)というものがあり、画面右上にある「ブラックボード」をクリックすると、ビヘイビアツリーに関連付けされたブラックボードを確認することができます。

ブラックボードは簡単に言えば、ビヘイビアツリーで使うパラメータ(変数)の格納場所のようなものです。ビヘイビアツリーで行動パターンを記述し、ブラックボードでそのパラメータを編集するようなイメージとなります。

ちょっと長くなってしまいますが、基本を知る為に、アンリアルクエスト5の初期実装のAI処理の流れを追ってみましょう。

アンリアルクエスト5のAI初期実装

プロジェクトの中で見るべきファイルは以下の通りです。(全てUnrealQuest5/AI配下に格納されています)

  • BP_UE5_Enemy:敵そのもの
  • BP_EnemyController:敵のブループリント(BP_UQ5_Enemy)に紐づけられたAIコントローラー
  • BT_Enemy:上記で説明したビヘイビアツリー
  • BB_Enemy:上記で説明したブラックボード
  • BTT_Enemy_Attack:敵がプレイヤーを攻撃する

それでは早速処理を追っかけてみましょう。

まずは、BP_UQ5_Enemyを開き、詳細タブのAI Controller Classを見てみましょう。

ここに記載されているBP_EnemyControllerとは、プレイヤーがゲームコントローラーやキーボードで動くのに対して、敵キャラクターがビヘイビアツリーで動くことを定義する為の設定を行う処理となります。

次にBP_EnemyControllerを見ていきます。BeginPlayから追っかけてみると、最初にUseBalckboardというノードがあります。これは上で解説した通りですが、ビヘイビアツリーに関連付けするブラックボードの生成処理となります。(正確には生成ではなく、使用宣言という感じですかね)

ブラックボードを宣言した後は、ブラックボードに追跡するキャラクターを設定してあげます。”ChaseActorKey”という名前で、プレイヤー(GetPlayerPawnで取得)をブラックボードに登録していることが分かると思います。

最後にブラックボードに待機時間を書き込んで、RunBehaviorTreeというノードを呼び出しています。これを呼び出すことで、敵はビヘイビアツリーに従って動くようになります。

次にビヘイビアツリーを解説します。

ビヘイビアツリーには条件分岐のSelectorノードと、順序に従って処理を行うSequenceノードがあります。アンリアルクエスト5の初期状態ではSelectorノードは存在せず、コメントにある通り「プレイヤーに近づく(プレイヤーはブラックボードに書き込み済み)」「プレイヤーの方を見る(これもブラックボードに書き込み済み)」「攻撃」「待機」を連続で実行しているだけです。

ビヘイビアツリーのタスクノードには最初から用意されているノードと、作成しなければならないノードがあります。例えばMoveToノードは最初から用意されているノードで、ブラックボードに書き込まれた座標や相手オブジェクトに向かって移動する為のノードとなります。

BTT_EnemyAttackノードは作成されたノードで、標準ノードだけでは実現できない動きは、ノードを作成することで動作させることが可能です。

実装開始

まずは、プレイヤーの刀にあたり判定を追加して、敵キャラクターにHPの概念を持たせていきましょう。これは初級・中級の解説編でも解説しているので、詳細は割愛します。(一応、プレイヤーと敵のBPは貼り付けておきます)

今回は敵のHPを2に設定しておき、2の時は通常攻撃で1になったら逃げ回るようにしてみます。

先ほど解説した通り、ビヘイビアツリーはブラックボードのパラメータを元に動作している為、なんとなくブラックボードにHPを入れてみれば良さそうな感じがしますね。やってみましょう。

BB_Enemyを開き「新規キー」をクリックして、Float型を選択して”HP”という名前を付けてください。

次に敵のHP更新時にブラックボードにもHPを書き込むようにしてみましょう。まずは敵のBPにカスタムイベントを作成します。名前は”UpdateBBHP”としました。ロジックはとても簡単で、敵キャラクターのAIコントローラーからブラックボードを取得して、ブラックボード上のHPに現在のHPを設定するだけの処理です。

作成したUpdateBBHPを呼び出す処理を書きます。HP更新処理後に呼び出すだけでなく、敵キャラクター生成時にも呼び出して、ブラックボードに初期HPを渡す必要がある点に注意してください。

まずは敵キャラクター生成時に呼び出し。

次に敵キャラクターHP更新時にも呼び出し。

これで、BP_UQ5_EnemyのHPとブラックボードのHPが連動するようになりました。

次にビヘイビアツリーの「デコレーター」を使って、HPが2以上の時だけプレイヤーに近づいて攻撃してくるというロジックを組んでみます。

ルートノードとSequenceノードの間にSelectorノードを新設し、Sequenceノードの上で右クリックして「デコレーターを追加」から「Blackboard」を選択します。デコレーターは、ブラックボードの値が〇〇な時だけこの処理を実行するという条件分岐的な機能を持っています。

デコレーターを追加したら詳細パネルにて以下のように設定してください。

  • オブザーバーを中止:Both
  • Key Query:Is Greater Than Or Equal To
  • Key Value:2
  • Blackboard Key:HP

これは、ブラックボードのHPが2以上の場合は、元々の処理を実行するという意味になります。実装した結果はこんな感じです。

この状態でプレイしてみると、プレイヤーの刀が一度でも当たった敵はその場に立ち尽くすようになります。これは、HPが2から1になったので、ビヘイビアツリーで定義された今までの動きができなくなってしまったからです。

後は、HPが1になった敵を逃げるようにすればOKです。

実際にプレイヤーから逃げるという挙動はUnrealEngineのEQSという機能を使えば実現可能ですが、今回はランダムで移動させてみます。

まずはビヘイビアツリーの画面から「新規タスク」を選択し、「BTTask_BlueprintBase」を選択します。すると「アセットに名前を付けて保存」というダイアログが表示されるので”BTT_RandomPosition”という名前で保存しました。

作成すると、自動的にBTT_RandomPositionのイベントグラフが表示されるので、敵プレイヤーがランダムで逃げ回る為の目標地点を設定するロジックを書いていきます。

イベントグラフ上でReceive Execute AIノードを表示させます。このノードはビヘイビアーから、この処理が呼び出された際にコールされるイベントとなります。

早速処理を書いていきたいのですが、ランダムで移動する先をブラックボードに持っておく必要があるので、まずはブラックボードにキーを追加しましょう。元々、プレイヤーを追いかけていたChaseActorKeyを流用すれば良いような気がしますが、これはActorを入れるもので、今回は座標を格納したいので新規でキーを追加することにしました。

「新規キー」をクリックしVector型を選択します。名前は”EscapePosition”としました。

ということで、このEscapePositionに座標を入れていく処理をBTT_RandomPositionに記述していきましょう。

敵キャラクターを中心に、半径1000以内で移動可能な座標をランダムで返却するノードを使って、その結果をSetBlackboard Value as Vectorノードでブラックボードに書き込んでいます。また、タスクの最後は必ずFinishExecuteで正常に終わったか否かを返却することを忘れないようにしてください。

これでランダム移動のタスクが完成したので、ビヘイビアツリーの実装を行います。

先ほど作成したSelectorからSequenceノードを作成し、そこで先ほど作成したBTT_RandomPositionと最初から用意されているノードであるMove Toノードを呼び出します。Move Toノードには移動先を指定できるので、ブラックボードに追加したEscapePositionを設定してみましょう。

プレイしてみると、HPが2の時は元気に攻撃を仕掛けてきた敵キャラ達が、一回切り付けられたら逃げ回るようになりました。

これで敵キャラクターのビヘイビアツリーを編集して敵が賢くなりました。

1日目上級クエストはAI・ビヘイビアツリー周りを理解していないと、ちょっと大変なクエストだったかもしれません。しかし、このように簡単に敵の動作を切り替えることができるビヘイビアツリーはゲーム制作に大きく役立つはずですので、学習しておいて損はないかと思います。

次回は2日目の上級クエスト「敵の攻撃を弾く仕組みを作ろう」を作ってみたいとおもいます。

No responses yet

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です