UE5でAIを使ってプレイヤーキャラクター以外の登場キャラ(ノンプレイヤーキャラクター:NPC)を自動操縦してもらいましょう。
ちまたにはビヘイビアツリーという新しい仕組みを使う動画・記事が多く見つかりますが、最初はもっと簡単なところから学習しましょう。
もちろんビヘイビアツリーを使うときにも無駄にはなりません。
UE5で8番ライクゲームの作り方解説動画第4弾の一部を切り出してサクッと解説します。
近づくとダッシュで迫ってくるタイルマンのように、魅力的な役者が登場する楽しいゲームができるようになります
前準備
前準備:キャラクターの準備
プレイヤーキャラのブループリントを複製し、メッシュとアニメーションを変更しましょう。
動画では玉ねぎちゃんにしました。スケルタルメッシュを玉ねぎちゃんに置き換えて、アニメーションはリターゲットしたものにしています。
マニーやクインなどのUE5のキャラをそのまま使う場合も何かしら変更することになるので複製して指定しなおしたほうが良いと思います。
カメラと自撮り棒は不要なので削除します(もしそのキャラクターを追いかけるカットムービーなどを予定している場合は残しても問題ありません)
また、デフォルトの状態だとカメラがこのキャラクターを飛び越えてプレイヤーを手前に写そうと回り込んでしまいます。NPCはカメラを無視するようにしましょう。
今回は、コリジョンプリセットをカスタムにして、カメラを無視するにチェックをつけます。
カプセルコンポーネントにも同じ設定があるので両方変えましょう。
ちなみにカメラ側でキャラクターを無視することもできます
また、プロはカスタムを禁止してプリセットを作りこむそうです(変えたくなった場合にアクタ一つ一つ確認するのが大変だったりバグの温床になるとのこと)
【UE5】コリジョン管理・処理に関する講演メモ・補足 : Collision Data in UE5: Practical Tips for Managing Collision Settings & Queries | Unreal Fest 2023 – ぼっちプログラマのメモ (hatenablog.com)
- ホグワーツレガシーの開発では、Collision設定に関するルールが整備されていなかったため、プロジェクトの規模・コンテンツ量が増えるにつれて不具合や対応コストが膨大になった
- そのため、初期段階からCollision設定に関するルールを作成し、各自がそれを守る・注意することが大事。また、それを継続するための仕組み・ツールづくりも重要
AIに制御してもらうので、プレイヤー用のイベントグラフ内の処理は一旦全部消しましょう。この代わりにAIに操作してもらうということです
↓全部選択して消します。
これでほぼ準備OKです。
前準備2:ナビメッシュの設置
AIに操作してもらうには、ナビメッシュバウンズボリュームというなんだか難しい名前の箱が必要です。これは「この範囲内を移動していいよ」と教えてあげるものです。
ルールを知らない友達に「ここからここまでは移動していいよ」という感じですね
とりあえずステージ全体を覆うサイズにひろげてみましょう
「P」キーを押すとどこが歩けるとAIが認識しているかを緑色で表示してくれます
レベル上に複数置くこともできますし、逆に入っちゃダメゾーンを決めるタイプや、おすすめしないけど通ってもいいゾーンというあいまいなものもあります。
ナビゲーション システムには、ナビゲーション メッシュの生成方法を変更できるさまざまなコンポーネントや設定が用意されています。変更できる内容としては、ポリゴンに割り当てられるコストなどがあり、これはエージェントがレベルを移動する方法に影響を与えます。
ナビゲーション メッシュを修正する | Epic Developer Community (epicgames.com)
近いけど危ない道と遠回りだけど安全な道どっちから行く?みたいなことを考えてくれるそうです
うろうろ
行動ごとにカスタムイベントを作りましょう
名前はなんでもいいですがうろつく処理なのでRandomWalkとしてみました。
AI Move Toというノードを使います
これは「目標」に向かって移動させるノードです。
Pawnのピンに動かしたいキャラ(Self参照)を指定するのを忘れないようにしましょう
省略してもセルフ扱いになってくれず動きません。
省略するとセルフになってくれるものとそうでないものわかりづらいなぁ
Acceptance Radius(許容する半径)は目標とどのくらいズレても成功とするかの誤差距離です。
5センチは近すぎるので適当に50くらいにしておきます
目標地点としてランダムな地点をDestinationピンに接続します
Radiusを200cmにすると半径2mの球内のランダムな地点を返します
原点は現在の自分の位置(Get Actor Location)を入力しましょう。
これで今いる位置から少し移動する処理が完成です
AIコントローラー用のクラスを新しく作ってそこに処理を書いている場合は、Self参照ではだめで、「Get Controlled Pawn」という、いま自分(AIコントローラ)が操作しているポーンを取得するノードでキャラクターを取得する必要があります。
AI Move ToとGet Actor Locationと両方
たどり着いたらちょっと待って再びうろつく処理を呼ぶようにし、開始時にもこのイベントを呼んで実験しましょう
ひたすらうろうろします
ためしに半径を広げてみると遠くまで行けるようになって走り出します。
遠くても歩かせたい場合はMax Walk Speedで調整してください
追っかけ
次は追いかけてくる行動を作りましょう。やることはほとんど同じです
AI Move Toのもう片方の目標設定ピン「Target Actor」を使います。
プレイヤーを追いかけたいのですが、追いかけるたびにプレイヤーを探すと処理が重くなってしまうので開始時に取得しておきます。
Get Player Characterを変数に保存します。
これでプレイヤーの情報にアクセスできるようになったので、追いかける目標としてAI Move Toの「Target Actor」ピンに接続しましょう
これだけで追いかける処理は完成です。
追いついたあともさらに追いかけ続けるように再度カスタムイベントを呼び出してみました。また、追いかけるのに失敗した場合も再チャレンジさせています。
Begin Playのうろうろイベント呼出しをこれに変えて追っかけるキャラクターにしてみましょう。
この辺は目的次第で変えてください。
とにかく追いかけ続ける鬼ごっこ系ゲームはこれでできますね。
逆に逃げさせたいときは、鬼役のアクターとの相対位置ベクトルをXY方向に-N倍するという計算で逃げる位置を計算できます。そこを原点にランダムにずらすと難易度を上げたりできますね。
追いついたら何かする
追いついたらジャンプや追いついたら攻撃という流れはこのように実現できます。
ジャンプは専用の「Jump」ノードがあるのでそれを呼べばよいでしょう。攻撃はJumpの代わりにカスタムイベントを作ってPlay Montageでアニメーションモンタージュを再生するとよろしいかと。
動画中でちらっと出してる攻撃のアニメはMixamoで拾ってきました。(剣を振りかぶるアニメ)
一定距離近づいたら追っかけくる(タイルマン)
8番出口でも印象的な壁のタイルに張り付いて擬態している例のキャラのように、一定距離まで近づくと追ってくるような、何かのきっかけで行動するパターンを作ってみましょう
AIに視覚や聴覚などを持たせる方法があります。
が、ここでは初級編として、もっと簡単にワープ装置と同じBoxコリジョンのオーバーラップイベント駆動型のイベントにしてみましょう。
狭い通路ではボックスコリジョンに触れたら動き出せれば十分ですね
ブループリントアクターを作成し、ボックスコリジョンを置き、
オーバーラップイベントを追加します
重なった相手がプレイヤーだったら敵キャラに対して追っかけモードに変える指令をだしましょう
敵キャラに指令を出すには敵キャラを知る手段が必要です。いくつか手段はありますが、ここでは簡単な作戦として、クラス名をもとにレベル内に存在するアクターを検索する方法をとりましょう。
探す処理は少し重いので、毎回ではなく開始時にやりましょう
Get Actor Of ClassでAIキャラのクラスのアクターを探し、変数に保存しておきましょう。
複数配置する場合はタグをつけておいてwith Tagで検索するなどの工夫が必要になります
レベルブループリントはレベル上のアクターを知っている状態で始められるのでそっちに任せるという作戦もアリです。
これをBoxコリジョンに重なったイベント(OnComponentBeginOverlap)から参照して、敵キャラの追っかけイベントを呼び出します。
あとは敵キャラ側の開始時に追っかけモードにしているのを外して最初は止まっている状態にすれば
「エリア内に入るイベントをきっかけに追っかける」タイルマン的な敵キャラクターが完成です。
普通に近づいても追ってきませんが、トリガ装置を設置してこれを踏んだら追いかけてきます。
BoxやSphereコリジョンを敵キャラ自体に追加してもOKです。
ただし、その場合そのコリジョンがワープ装置にぶつかってワープしちゃうなどの想定外トラブルにも気を付けましょう。
つづく
長くなっちゃったので2本に記事を分けます。
コメント
いつもありがとうございます!
8番ゲームとは直接関係ないかもしれませんが、プレイヤーがループコリジョンに入ってループした時にAIキャラクター(動的アクター等)も一緒にループしてくれることはできますか?
ループした途端、追ってくるキャラが居なくならないようにしたいです!
ありがとうございます。
ついてこさせたいキャラの参照をワープ装置に渡せさえすれば、
ワープ装置とそのキャラの相対位置関係でワープさせること自体はこの連載の最初の記事と全く同じ計算のコピペで実現できると思います。
あとはどういう条件で付いてこさせたいか次第ですね。
たとえばプレイヤーから一定距離以内のキャラクターをワープさせたいなら
GetAllActorsOfClassノードで指定のクラスのActorを一旦全て取得して、GetDistanceToノードで距離を取得できます。
仲間とかだったら仲間にするイベントで参照を保存しておけばよいです。
やってみました。
追ってきているかどうかのフラグみたいなものも必要かもしれません。
https://yossi40-100.com/ue5study11/