UE5のCharacterクラスはとても便利であり、非常に汎用的に作られています。おそらくUE経験者でCharacterクラスを使わずにキャラを実装したことがない人はほぼいないのではないでしょうか。しかし様々な事情によってはCharacterクラスを使えないこともあります。
例えば負荷の問題。Characterクラスは汎用的に作られている故に、CPUに対する負荷はかなり高いものとなっています。他にもコリジョンの形状をカプセル以外にしたいという要望もあると思います。簡単なキャラクターを実装したいのに、Characterクラスでは機能が過剰にオーバーしていたりするので、少しでも軽量な、そしてシンプルなキャラクターを実装したいとうニーズはあるはず。
今回はPawnクラスを使ってUE5標準のサードパーソンキャラクターに近いものを実装してみるというお題でいってみましょう。
以下はUnreal EngineとPawnクラスとCharacterクラスに対する公式の資料となります。
BPの作成とコンポーネントの追加
今回はUE5のサードパーソンテンプレートに同梱されている、"BP_ThirdPersonCharacter"に可能な限り似せていきたいということで、BPも似たような構成にしていきます。
中身のコンポーネントはこうなっています。
基本的な構成はほぼ同じです。
Capsule → カプセルコリジョン。コンポーネントのルートとして追加
SkeletalMesh → キャラのメッシュ。"SKM_Manny"を追加し、Anim Classに"ABP_Manny_C"を設定
SpringArm → カメラオフセット。"BP_ThirdPersonCharacter"からそのままコピー
Camera → カメラ本体。上記同様"BP_ThirdPersonCharacter"からそのままコピー
FloatingPawnMovement → Pawn版"CharacterMovement"。"Max Speed"を"600.0"に修正
これらを一通り追加しておきましょう。また親子関係も重要なので追加時に親子が間違っていないかも確認しておいてください。
移動とカメラ操作のコピー
基本的に"BP_ThirdPersonCharacter"を模倣する形をとるので、メインの移動とカメラ操作はそのままコピーします。以下の画像部分は全てコピーして自作のBPのイベントグラフへと、もっていきましょう。
ジャンプ部分のみ後ほど改変することになります。
重力と物理とコリジョン設定
現状ではそのまま使っても重力の影響を受けず、Capsule Collisionコンポーネントの修正が必要です。
まずはSkeletal Meshの高さに合わせて、"Capsule Half Height"を"90.0"に設定しておきます。Skeletal Mesh側の位置はZを"-90.0"、回転のZを"-90.0"に設定しておきます。これで大体メッシュとコリジョンが重なるようになります。
次に物理カテゴリーにある"Simulate Physics"をオンにします。これで重力の影響を受けるようになり、空中でも落下することができるようになります。
更にコンストレイントの設定から、"回転をロック"のXとYとZを全てチェックします。これによりカプセルが一切回転しなくなってしまいますが、物理によって滅茶苦茶な方向に曲がるようなことはなくなります。
次はコリジョンの設定から"コリジョンプリセット"を"Pawn"にしておきます。これによりCapsule Collisionが地面や壁などにコリジョンとしてヒットしますので、突き抜けるようなことがなくなります。
これらの設定を施すことで、ひとまずキャラが最低限のコリジョンを持つことができるようになりました。もちろん今回の手順はCapsule Collision以外にも適用可能ですので、必要に応じて変えてみてください。
ジャンプの実装
Characterクラスではないので、当然"Jump"ノードは使えません。重力にも影響を受けつつ、しっかりとジャンプ出来るようにしていくには少し特殊な実装が必要となります。
まずはキャラクターが空中にいるかどうかの判定をとれるようにします。
Event Tickから毎フレーム"LineTraceByChannel"で下向きのレイキャストを行います。そこでヒットしていた場合は"Is Falling"という変数に"NOT Boolean"で反転した結果を格納しておきます。飛ばすレイの長さはZ方向のみ下になるよう"-150.0"という数値を入力していますが、必要に応じて修正してください。
次にジャンプ部分を改変します。元々ジャンプ処理があった部分を削除し、"Is Falling"がFalseの場合にのみジャンプができるようにします。肝心のジャンプについては"Add Impulse at Location"ノードを使って衝撃場を発生させることで物理的にジャンプさせます。
かなり強引な方法ではありますが、Capsuleに衝撃をZ方向に与えることで上に飛ばすことが可能です。"Impulse"のZについてはかなり高い数値を入れておく必要があります。参考までに今回は"20000.0"という値を入れています。この数値を変えることでジャンプ力については変更可能です。
移動時の向き変更
現状のままですと、移動を行った際にキャラクター向きの変更を行うことができません。この部分についてはCharacterクラスと違い、自力で計算させてあげる必要があります。先にノードを提示します。
Event Tickから毎フレーム計算をします。Jumpの処理もあるので、後ほど結合します。
"Floating Pawn Movement"が移動速度を保持しているので、"Velocity"を取得し、正面ベクトルをRotateに変換します。Skeletal Meshは最初にZを"-90.0"回していますので改めてZに補正をかけておく必要があります。"RInterp To"ノードでSkeletal MeshのWorld Rotationから取得したCurrentと上記回転値をTargetで渡して、"Set World Rotation"に結果を反映することで少しずつ綺麗に回転させることができるようになります。
ただし常に回転を行うと余計な回転が発生してしまうので、あくまでもVelocityが一定値以上(ここでは100.0)の時にのみ回転を行います。それが冒頭にある"Branch"ノードで判断している部分になります。これで一定速度以上の場合にのみ回転が行なわれることになります。注意点としてはこれはアクターが回転しているわけではなく、あくまでもSkeletal Meshが回転しているということです。回転操作をする際には注意してください。
ちなみに最終的なEvent Tickの全体は以下のようになりました。
Animationブループリントの修正
最後にAnimationブループリントも修正していきましょう。そのままでは正常にアニメーションが行われません。まずは初期化時にPawnとFloatin Pawn Movementを変数として保存しておきます。
次に"Event Blueprint Update Animation"の中身の修正です。
元々"Character Movement"で処理していたVelocity計算を、"Floating Movement"のものに差し替えます。
これで"Ground Speed"に正常な移動スピードが格納されます。
次にそのすぐ下でやっている加速度チェックをそのまま使うとやはり動作しないので修正します。
上記画像の通りで動きますが、ANDノードに繋げずに接続する方法でもOKです。
最後に空中判定をしている"Is Falling"も修正します。
元々Pawnの方で"Is Falling"を設定しているのでそのまま渡してしまってOKです。これで全て揃いました!
実際に動いている様子
実際に動かしてみました。
Characterクラスを使わずに、Pawnクラスのみでサードパーソンのキャラクターを実装してみた。#UE5 #UE5Study pic.twitter.com/uYJXJh15RW
— alwei (@aizen76) 2024年1月30日
まだまだジャンプ周りの挙動をそのまま再現するのは難しいですが、かなり近いものになっていると思います。ちょっとしたキャラクターとして使う分には十分でしょう。
あまりCharacterクラスを使わずにPawnでキャラを実装することは少ないかもしれませんが、こういう地味なノウハウがどこかで役立つのではないかと思いますので、気になった方はぜひ試してみてください。