UE5で敵を巡回させたい(ビヘイビアツリー)
※素人による記事の為、間違いがある可能性があります
※個人用備忘録ですが、何かご指摘ございましたらコメント頂けたらと思います
AI関連記事紹介
目標:下記を満たすAIを作る
・決まったルート巡回している
・プレイヤーを見つけると追ってくる
・見失うと巡回に戻る
公式のビヘイビアツリーチュートリアルを参考
AI周りの準備
・適当な場所にNPC関連を入れるフォルダを作成
・プレイヤーを作ったフォルダにコピーして、リネーム
・フォルダ内にAIcontroller Behaviour tree Blackboardを作成
・BehaviourTreeとBlackboardを作成
・それぞれ
AIC_ENA
BT_ENA
BB_ENA
とリネーム
・Blackboardにキーを追加
Player プレイヤーとかその味方を格納
PatrolLocation 巡回する地点
※公式チュートリアルではBool値で「Playerを見つけたかどうか」
のブラックボードキーを作成していますが、無くてもいけます。
・NavmeshBoundsVolumeを配置、スケールをレベルに合わせる
・BehaviourTree を開いて任意の Blackboard が適用されているか確認
(BBが複数あると意図しないのが勝手に設定される事がある)
・AIcontrollerを開いて下記のように組みます
※なぜEvent begin playでは無く Event On Possess(AIcontrollerがCharacterを持った時のイベント)だったのかは詳しくは下記リンク参考
・AIPerceptionを追加、SenseConfigから視覚を追加
・基本中立のやつしかいないので、Neutralをオン
詳しくは別記事を参考↓
・準備は完了
Characterの準備
敵AIブループリントを開く
イベントグラフ内は全て削除
・カメラなどいらないコンポーネントは削除
・Max walk speedを120にしておきます。
・Auto possess AI (下に説明あり)を設定
・AIcontrollerを指定する
・Auto possess AI AIcontrollerがCharacterを持つタイミングを選べます
参考(リンク先の真ん中ちょい下)
プレイヤーBPを開く
Player タグを追加(tagと検索した方が早い)
・UE5グレイマンのアニメーションBPを開きます
・デフォルトのままだとNPCがアニメーションなくなるので画像のようにします。
詳しくは下記リンク↓
ビヘイビアツリーでロジックを組む
ビヘイビアツリーでは「コンポジット」ノードで流れを管理します
・Selectorで大きな分岐を作って、Sepuenceでタスクを実行させます
なので以下の様に組んでリネームもします。
・タスクノードを追加する
具体的に何をするのかあらかじめ用意されているのがタスクです
・Waitを追加、時間を1秒に。Rotate~はBlackboardkeyにPlayerを設定する
・ここで一旦敵キャラクターBPを開き、Use Controller Yaw をオンにしておきます(BTのRotate toタスクを使う時は必ずここをオンにする)
・新規カスタムタスクを2つ作成
BTT_SpeedUp
BTT_FindPatrolPoint
にリネーム
・下記の様にタスクを組みます
ChasePlayerのMove toを選択
BlackboardKeyをPlayerに
Patrol下のMove toの BlackboardKey は PatrolLocation を
Patrol下のWaitは WaitTime4秒 の RandomDeviationを1秒に
(そうする事で±1秒ランダムで変化)
これでビヘイビアツリーは一旦完了
タスク SpeedUp を組む
ここではタスクSpeedUpから敵の速度を変える仕組みを作ります
ビヘイビアツリーのタスク内で直接サブオブジェクト(キャラクター)
のプロパティを変更するのは好ましくない(公式チュートリアル参考)
らしいので、敵キャラクターBP内で関数を作成して
タスクからFloat値を渡せるようにします。
・敵キャラクターBPの BP_ENA を開き、下記の様に設定
・Max walk speedと検索してノード追加、後は画像の通り
・BTT_speedupタスクを開き、イベント Receive Execute AI を作成
・下記の様に組む
・ビヘイビアツリー内でChaseSpeedが変更可能になっているか確認
これでタスクを開かなくても速度を変更できます。
タスク Find Patrol Point を組む
ここでは巡回するルート地点を取得するロジックをタスクFindPatrolPointとして組んでいきます。
目標イメージ:PS1のメタルギアソリッドみたいに十字に巡回する敵
参考↓
まず巡回ルート地点をブループリントの変数として作ります
・右クリック > ブループリント > Actor で新規ブループリント作成
BP_PatrolRoute にリネーム
・BP_PatrolRoute 内で Vctor の配列変数を作成
・BP_PatrolRouteを適当な位置にD&D、さっき作った配列変数を+で追加
・1つ目はそのまま、2つ目はパラメーターいじって移動させて選択できるようにし、任意の位置にビューポート上で直接動かします。
・画像のようにしました。
・巡廻速度を設定します
FindPatrolPointタスクを開き、Patrolspeed変数を作り、目ボタンをオン
BP_ENAで作ったUpdateWalkSpeed関数を呼びます
・巡回地点の位置情報を得る為に、配列変数を取得します
Patrol Route Array変数を取得したいが、別アクターの変数なので
Get Actor of Class で BP_PatrolPoint を取得します
・PatrolRouteArrayから巡回地点の位置情報を取得してブラックボードキーに渡せるようにします。
①のGETで配列の何番目かの指定(integerによる)をしています
②の TransfomLocation は Tピン と Locationピン を足した値をワールド座標に変換してくれるので、巡回地点のワールド座標が取得できます。
③でブラックボードキー変数を作成して一旦位置情報を保管します(後でBT上でBBキーと結びつける)
・取り出す配列に1を足していき、最大になったら0に戻す処理を作ります
integer変数を作成PatrolIndexとリネーム、配列の何番目かを指定します
①で毎実行毎に1足します
②で配列のいくつあるのか取得します
③で配列のMAXよりは現在小さいかどうか判定します
※配列が0~5まであるとしたら LENGTH は6を返す為
6番目は存在しない為、6を含めないように < を使用
④SelectInt は true であれば A を返し、false であれば B を返すので
⑤で配列の最後になったら0をPatrolIndexに入れて最初の地点に戻します。
・最終的にこんな感じになります
・ブラックボードキーに巡回地点の位置情報を渡します。
FindPatrolPointタスクは完了
他にも色々な位置の取得方法がありまつ
Playerを見つけるロジックを組む
・敵NPCの AIcontroller を開き
On Target Perception Updated イベントを作成
公式を参考
・Playerかどうか判定する
①Break AIstimulusで色々取得できるが、感知に成功したかどうか取得した
・PlayerじゃなかったらブラックボードキーPlayerを空にする
set timer~~は○○秒まって実行できるノードです
①プレイヤーを見失ってから諦めるまでの時間を設定
②カスタムイベントを作成、適当にリネーム
③はブラックボードキーの名前
Set timerノードの解説は以下の記事で
・Playerだったら ブラックボードキーPlayerを設定
①は変数に昇格してもいい
②は先ほど作ったののコピペ
③でAIperceptionから取得したPlayerを設定
・こんな感じになる
プレイヤーを見つけたらChasePlayerを実行
ビヘイビアツリーでChasePlayerをプレイヤーを見つけた時だけ実行できるようにします。
・Blackboardデコレーターを追加する
ChasePlayerを選択 > 右クリック > デコレーター追加
・ブラックボードキーPlayerに値が設定されてれば実行させるようにする
Blackboardデコレーターはブラックボードキーに値が設定されてるかどうかを条件式にできます。
今回は「ブラックボードキーPlayerに値が設定されてれば実行」させたいので、画像の様にします。
詳しい説明はこちら
これで終わりです、Playして確認してみてください!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!疲れた!!!!!!
この記事が気に入ったらサポートをしてみませんか?