UE5でAIを使ってプレイヤーキャラクター以外の登場キャラを自動操縦しましょう。
本記事ではルートを巡回する処理について解説します。
UE5で8番ライクゲームの作り方解説動画第4弾の一部を切り出してサクッと解説します。
いっしょに無限ループしている例のおじさんみたいなキャラクターをゲームに登場させましょう。
前準備
前準備:キャラクターの準備
BP_ThirdPersonCharacterを複製して作りましょう。詳しくは前編の記事で。
メッシュとアニメーションBPの置き換え、カメラとブームの削除、イベントグラフをすべて削除し空っぽにします。
前準備2:ナビメッシュの設置
AIに操作してもらうには、ナビメッシュバウンズボリュームが必要です。これは「この範囲内を移動していいよ」と教えてあげるものです。とりあえずレベル全体を覆うサイズに広げてみましょう。
巡回・決まったルートをパトロール
巡回ルート管理クラスとして、新しくブループリントアクタを作成し「スプラインコンポーネント」を置きましょう。
このスプラインの点をAIに移動する目標にしてあげる作戦です


UE5.3.2では「Spline」だったのが、UE5.4では検索文字が「スプラインコンポーネント」になってアレ?ってなりました
あと「スプラインメッシュコンポーネント」はまた別な用途です。
スプラインでなくても構いません
たとえばUE5極め本では「TargetPoint」という位置情報だけのアクタを複数配列で管理していました(さらに構造体という仕組みも利用)
「Begin Play」で開始時にスプラインの点の数を把握しておきます
始点が0番で番号で位置情報をもらうので、この時点で1引いておきます(お好みですが)

あとは、何番目というインデックスを受け取ってその点の位置情報を返す関数を作ります
関数のプラスボタンから新規関数を追加します

受け取るインプットに整数型を追加しアウトプットはベクトルで位置情報を返します

「Get Location at Spline Point」でスプライン上の点の位置情報を取り出します
Worldで「ワールド座標」に変更するのが重要です
(ローカルだとほかのアクターがレベル上で動くための目印としては原点の情報も必要で使いづらいです)

終端まで行った後は引き返すなどはゲーム仕様で変えるものですが
ここでは最終地点より大きい指定が来たら(ゴールついたあと再度呼ばれた状況なら)常に最終地点の情報を返す仕様にしています

Minはどっちが大きいか判定して小さいほうを返す処理をまとめてくれた便利なノードです
Maxもあるよ~(上限ガードしたいときにMinってなんか感覚と逆でまちがいがちです)
ナビルート側は完成なのでNPC側でこれを参照します
探す処理が重いので、これもBegin Play時に1回だけにしておきましょう
「Get Actor Of Class」でさきほどのスプラインを入れたブループリントクラスのアクタを探しましょう。複数設置する場合は「Get All Actors …」を使いつつForループなどで処理しますが、
ややこしくなるので割愛します。

今回はおじさんは最初から歩くようにしてみます。カスタムイベント「Walk」を作ってそれを呼び出しています。
では、歩くイベントの最初にさきほどの巡回ルート管理クラスから次の目標をもらいましょう

いまどこまで進んだかのインデックスは変数にして、進んだら更新するようにしましょう。スプライン側にインデックス管理を持たせている例もありました。
複数人同じルートで歩かせたい場合はそれだとうまくいかないので用途に応じて変更が必要です。
※どんどんインデックスが増えていくと、どこかのタイミングでインデックス変数がオーバーフローするかもしれないのでご注意ください
これで次のポイントにたどり着いたらさらに次のポイント目指して進むロジックの完成です
スプラインはポイントをクリックした状態で移動させたり、Alt押しながら移動で点を増やしたりして線を描く仕組みです。
ゲーム中は表示されません。ナビメッシュで緑色になって歩けるところに点を打って巡回経路を決めましょう

実行して確認します。無事歩きましたか?

実行のオプションで自機を表示しない「シミュレーション」にすると、確認しやすいかもしれません。
補足
スプラインをキャラクター自体に持たせたほうが楽じゃないかと思ってやってみましたが、
キャラクターが移動するとスプラインの原点も移動しちゃって想定と全く違うルートを歩き出すという面白いバグになりました(;’∀’)

親子関係トラブルには気を付けましょう
じろじろ
最後にこっち見てくる仕組みを作ります
これはキャラクターそのものはそのままで顔の回転角度をアニメーションで制御できます
Look Atというその名の通りのノードがあるので、これをIdle(待ち状態)のアニメーション出力の前に挟みます(このとき自動的に間に変換ノードがさらに挟まります)

どこを見るかというターゲットをLocationを選び、ピンにすることで自キャラの位置を外部入力させられます
これで変更対象の骨で頭を選ぶことで頭の正面を目的のほうに向けて回すアニメを待ち状態のアニメに加算する仕組みです


イベントグラフの周回処理のシーケンスノードに出力Pinを追加して、プレイヤーキャラクターを取得し、位置を取得すればいいのですが、キャストが必要でした
また自キャラそのものの原点は中心なのでソケットで頭を指定しています


未検証ですが、キャストというよりヌルじゃないかのチェック(検証済をゲット)が必要なのかもしれません。キャストは成功しないと次に進まないので実質それを含んでいます。
IdleだけでなくWalkにも同じ処理を入れておく(コピーでOK)と、待っているときだけじゃなくて歩いているときもこっちを気にしつつ歩いてくれます。
首がヤバイ角度に曲がる問題
一気にホラーになってしまうのでビフォー画像は割愛します(^▽^;)
回転可能な角度等を制限してあげましょう。50度に3秒かけて回る首にやさしい設定にしました


マネキンさんはこうなるけど、最初からリグで角度指定してある場合はそっちが優先されそうな気もします
(未検証なので推測ですm(_ _)m)

おわりに
お疲れさまでした。
ちなみに動画で控室スタンバイ中のキャラには、IDLE状態にMixamoで拾ってきた「StandingW_BriefcaseIdle」というカバンもって時計を見るアニメーションを設定しています。
コメント