|
執筆バージョン: Unreal Engine 5.7
|
こんにちは!今回は第26回ぷちコンのテーマ「だん」にちなんで、
プレイヤーが近づくとついてくる集団を作ってみましょう!
完成イメージはこちら!
・プロジェクトを用意しよう
まずはサードパーソンテンプレートでプロジェクトを作成します。

プロジェクトが作成されると自動的にLvl_ThirdPersonが開かれます。ここでプレイボタン(緑の矢印ボタン)を押してみましょう。
ゲームが開始し、プレイヤーを操作することができます。
Escキーを押すとゲームを終了することができます。


・カメラの視点をトップダウンにしよう
まずは、サードパーソンテンプレートは自分で視点を移動することができるので、プレイヤーの上部から見下ろす視点で固定するようにします。
サードパーソンの視点や操作で進めたいという方は、この項目を飛ばして「・近づいてくるキャラクターを作ろう」の項目に行ってしまって大丈夫です!
コンテンツドロワーを開いて、コンテンツフォルダの中のThirdPersonCharacterフォルダの中にあるBP_ThirdPersonCharacterを開きます。

カメラを固定するため、CameraBoomを選択したあとに以下の手順で行います。

①「カメラ位置を固定するためInherit Pitch, Inherit Yaw, Inherit Rollのチェックを外します。
②CameraBoomのY方向の回転を-50°にします。
③TargetArmLengthの大きさを1000にします。
これらの手順を行ってビューポート内で以下の画面になっていたらバッチリです!

しかしこのままだと、マウスの位置によって進行方向が変わってしまい操作に違和感が出てしまうので、BP_ThirdPersonCharacterにもうひと手間加えます。
EnhancedInputAction IA_MouseLookというノードからつながっているピンにカーソルを合わせて右クリックを押し、「このリンクを解除」を押します。

この操作によって、マウスによってカメラが移動しなくなり、WASDキーで進行方向に進むことができるようになります。
これでプレイをしてみると…

上からの視点でプレイできるようになりました!
これらの操作を踏むことでサードパーソンの操作方法でトップダウンテンプレートと同様の視点で進めていくことができます。
・近づくとついてくるキャラクターを作ろう
次にプレイヤーが近づくと追従してくるキャラクターを作成します。コンテンツドロワーからBP_ThirdPersonCharacterを右クリックして「複製」を押し、
新しく複製したブループリントをBP_ChildCharacterのような名前にしておきます。


次にプレイヤーと見分けがつくように見た目を小さくします。
複製したBP_ChildCharacterを開き、Meshを選択し、トランスフォームの拡大・縮小のX, Y, Zをすべて0.5程度にします。

ビューポート上で確認すると…

プレイヤーの半分のサイズのキャラクターとなりました!
このキャラクターにプレイヤーを追従する機能を実装します。
・追従する機能を実装しよう
まずは、BP_ChildCharacterの追従する機能を実装します。
BP_ChildCharacterを開き、イベントグラフに移動します。Tickノードの白いピンからAI MoveToと検索し、AI MoveToノードを配置します。


AIMoveToノードのPawnピンはだれが追うのか、Distinationピンはどの位置に向かうかの情報を知る必要があります。今回はChildCharacterにPlayerCharacterの位置まで移動してほしいのでPawnピンに自分自身、Distinationピンにプレイヤーの座標を入力していきます。
何もないところでselfと検索し、selfと入力しGet a Reference to selfを追加します。

これをPawnピンに入力します。追従する座標はプレイヤーの座標なのでGetPlayerPawnからGetActorLocationをつなぎ、プレイヤーの座標を取得します。これをDistinationピンに入力します。さらにAcceptanceRadiusピンの値を100程度にしておきます。これにより、Childに取り囲まれることを軽減します。

次に、詳細パネルでAIControllerと検索して、AIコントローラークラスという項目をDetourCrowdAIControllerにしておくとBP_ChildCharacter同士でよけあってくれるようになります。

これでBP_ChildCharacterがプレイヤーに向かっていくようになりました。BP_ChildCharacter側の準備はこれで完了です!
今はBP_ChildCharacterがどこを移動していいのかわからない状態のため、移動できる範囲をNavMeshBoundsVolumeを用いて教えてあげる必要があります。

デフォルトのナビメッシュバウンズボリュームは小さいので拡大縮小の項目を20倍程度にし、位置も調整して地形をすっぽりと包むようにします。

キーボードのPキーを押すことで以下のようにAIの移動できる範囲を色付きで表示させることができます。

ここで試しに実行してみましょう。BP_ChildCharacterをドラッグしてレベル上にドロップし、たくさん配置します。


そして実行してみると…
BP_ChildCharacterがプレイヤーについてくるようになりました!
・プレイヤーが近づいたら追従するようにしよう
今は常にBP_ChildCharacterが追従している状態なので、プレイヤーが近づいたらBP_ChildCharacterを追従させる機能を実装します。
まず、BP_ChildCharacterを開き、Boolean型の変数FollowPlayerを作成します。

追従する機能はこの変数がtrueの時のみ実装することにします。 そのためBキーを押しながら左クリックして、Branchノードを出します。先ほど作成した変数をドロップしてGet FollowPlayerとして、Branchノードの入力のConditionピンにつなぎます。

これでFollowPlayerがtrueのときのみ追従してくるようになります。
続いて、この変数を切り替えるカスタムイベントを作成します。
イベントグラフ内の何もないところを右クリックし、Add Custom Eventと入力してカスタムイベントを作成します。このカスタムイベントにはChangeStateのような名前を付けておきます。

一度コンパイルしてから詳細パネルの一番下のインプット項目の右側の+マークをクリックして、カスタムイベントの入力引数を作成します。これもBoolean型で作成し、InFollowPlayerのように名前を付けておきます。

このカスタムイベント内で先ほど作成した変数FollowPlayerをイベントグラフ内にドラッグアンドドロップし、Set FollowPlayerとしてChangeStateの実行ピンとつなぎます。

今後、追従してくるかどうかを変更するときはこのイベントを呼ぶことになります。
次にプレイヤーが近づいたときに追従する機能を実装します。
プレイヤーのブループリントクラスBP_ThirdPersonCharacterを開きます。
コンポーネントパネルからCapsuleComponentを選択し、追加からSphereCollisionを追加します。これをCollectCollisionのような名前にしておきます。



黄色の範囲が当たり判定の大きさとなるので、少し大きくしておきましょう。作成したCollectCollisionを選択し、詳細パネルの拡大縮小を今回はすべて8程度にしておきます。

再度、CollectCollisionを選択し詳細パネルからOnComponentBeginOverlapを選択し、+ボタンを押します。


上図のような赤いノードが出てくるかと思います。これはCollectCollisionに触れたときに実行されるイベントです。
ここからこの当たり判定に触れたものがBP_ChildCharacterかどうかを判定するため、赤いOnComponentBeginOverlapから白いピンを伸ばしCastToBP_ChildCharacterノードを追加します。
CastToBP_ChildCharacterノードのObjectピンにはOnComponentBeginOverlapノードのOtherActorピンをつなぎます。OtherActorには当たり判定に何が当たったかの情報が入っています。

Cast To BP_ChildCharacterノードのAs BP Child Characterピンから引っ張ってChangeStateノードを呼び出します。当たり判定に触れたとき追従モードをオンにしたいのでInFollowPlayerピンにチェックを入れておきます。

これでBP_ThirdPersonCharacterの実装は完了となります!
実際に動かしてみると…
プレイヤーが近づくとBP_ChildCharacterが追従してくるようになりました!
・追従してくるスピードを調整しよう
プレイヤーとの距離に応じてスピードを変更する実装をします。BP_ChildCharacterを開き、何もないところで右クリックしてGetPlayerPawnからGetActorLoacationをしてプレイヤーの位置を取得します。再度何もないところで右クリックしGetActorLoacationを行います。これはデフォルトだと入力がself、つまり自分自身であるため何も入力しなくても自身のいる座標を返してくれます。この出力ピンから線を伸ばし、Distanceと検索し、Distance(Vector)ノードを追加します。

これにより、BP_ChildCharacterとBP_ThirdPersonCharacterとの距離を出すことができました。
この戻り値をMapRangeClampedノードに入れます。このノードは入力された値がInRangeAからInrRangeBの間で遷移するときに、OutRangeAからOutRangeBまでの値の出力を行うというノードです。
ここでfloat型の変数DefaultMaxWalkSpeedを作成し、MapRangeClampedノードの出力との積をとります。これによりプレイヤーとの距離に応じて0.5~20までの値になりその後の処理に続きます。

CharacterMovementをコンポーネントからドラッグアンドドロップしてきて、ピンを引っ張ってSetMaxWalkSpeedと入力します。このノードの入力のMaxWalkSpeedにさっきとった積を入れます。

これでMaxWalkSpeed、つまり歩く最大の速さがプレイヤーとの距離に応じて増減できるようになりました。
これで実際に試してみると…
プレイヤーとの距離に応じて速度を調整しながら追従してくるようになりました!
速度の調整がない状態と比べて自然な動きになっていると思います!
おまけ
現在、ChildCharacterがカメラとの間に入ったときにすごく近くの視点になってしまうことと、ChildCharacterに阻まれて動けなくなることがあると思います。これらを解決する方法の一つを実装していきます。
・ChildCharacterがカメラを遮ることの解消
BP_ChildCharacterがカメラとの間に入ってくると無理やりプレイヤーを映そうとして、極端にカメラが近くなってしまうということがあります。

解消するためにはBP_ChildCharacterを開き、CapsuleComponentを選択します。詳細パネルからコリジョンと検索して少し下にスクロールして、コリジョンの中のコリジョンプリセットという項目をCustomにします。そしてコリジョンレスポンスのCameraを「無視する」にすると、ChildCharacterによってカメラが遮られなくなります。

同様にして、コンポーネントパネルからBP_ChildCharacterを選択し、コリジョンプリセットをCustomにし、Camera項目を無視するにします。
これにより、Childにカメラを遮られることなくプレイができるようになります!
・ChildCharacterに阻まれることの解消
ChildCharacterに囲まれて動けなくなることを解消するための機能を実装していきます。まずは、メインエディタの画面上部の編集を選択し、プロジェクトの編集を選択します。

左の項目の部分をスクロールし、「エンジン」の中にある「コリジョン」をクリックします。

するとObjectChannelsという項目があるので、「新規のオブジェクトチャンネル」をクリックします。名前にChildCharacter、デフォルト応答にBlockを設定しましょう。

これで承認を押し、BP_ChildCharacterを開きます。BP_ChildCharacterをクリックし、詳細パネルのコリジョンの中のコリジョンプリセットを見つけます。
ObjectTypeをChildCharacterに変更し、プレイヤーを貫通したいのでPawnを無視するにします。ChildCharacter同士は重ならなくていいのでChildCharacterはブロックにしておきます。CapsuleComponentを選択して同様の設定を行っておきます。

次にプレイヤー側の設定です。BP_ThirdPersonCharacterを開き、BP_ThirdPersonCharacterを選択し、詳細パネルのコリジョンプリセットを見つけます。ChildCharacterを貫通したいため、ChildCharacterを無視するにします。CapsuleComponentでも同様にChildCharacterを無視するにしておきます。

ChildCharacterはデフォルトでブロックに設定したのでCollectCollisionを選択し詳細パネルからコリジョンのChildCharacterをオーバーラップにして、近づいたら追従に切り替える機能をできるようにしておきましょう。

これらの操作を行った後、プレイしてみると…
プレイヤーはChildを貫通して移動することができるようになりました!
プレイヤーがChildを押してどかすような方法もあるので用途に合わせていろいろと試してみてください!