UE で外部からの物理の影響を (それなりに) 受けるキャラクターを作る

第22回UE5ぷちコン|株式会社ヒストリア で以下の作品を提出しました。

www.youtube.com

このゲームはシンプルなウォータースライダーですが、キャラクターがジャンプ台や噴水といった外部からくる物理の影響を受けるようになっています。
それに加えて、(ジャンプを除けば)現実でのウォータースライダーと同様にプレイヤーはキャラクターに対して身体の左右の角度を (Yaw 軸) 緩やかに変えることしかできません。
当然、ジャンプ中も方向転換等はできません。

とても操作に不自由があるゲームですし、物理に頼っているうえでの理不尽な挙動もあるのですが、なんとかゲームっぽくまとめることができたのではないかと思います。

キャラクターが物理の影響を受ける

今回のゲームにおいて、「キャラクターが物理の影響を受ける」には2つの観点があります。

  1. キャラクターが「外部からの力」を受けて、位置や回転が変わる
  2. キャラクターのメッシュが「外部からの力」を受けて、位置や回転が変わる

ここでの「外部からの力」は AddForceAddImpulse のようなものや、他の Simulate Physics なオブジェクトとの衝突、そして重力もそうですね。

粗いですが以下の画像でいえば、ジャンプ台になっている雲からの力を受けて「キャラクター」が物理的に上空に跳ね返され、それと同時に「キャラクターのメッシュ」も加速度や重力の影響を受けて手足がバタバタします。

以降ではそれぞれについてみていきます。

キャラクターが「外部からの力」を受ける

ここに関しては Mover plugin に 5.4 から試験的に実装された「Physics Based Character Movement」を使っているだけです。

Unreal Engine 5.4 Release Notes | Unreal Engine 5.5 Documentation | Epic Developer Community

Physics Based Character movement is a new Experimental feature we are building into the Mover plugin which provides for two-way physics-based interaction between the character and its environment.
- The system uses movement modes created in Mover and takes the output movement as a target motion for a physics representation of the character.
- The character imparts forces on the parts of the physics world it is interacting with, and physics forces and constraints can in turn affect the movement of the character.
- Multiplayer physics-based motion with rollback and re-simulation is supported using Networked Physics.

Mover plugin について把握したい方は以下の記事がとても参考になります。(私もこちらで知りました)

UE5 Character Mover 2.0とは - Let's Enjoy Unreal Engine

Quick Start

当然ながら UE 5.4 以上が必要です。

Plugin の有効化

まずは Mover と Mover Examples の plugin を有効化します。

Mover Examples が Engine/Plugins のフォルダにあるのが確認できます。
まずは、Maps フォルダにある L_PhysicsSimulatedCharacter を開いて遊んでみるのもいいかもしれません。

Example から PhysicsMannyPawn をコピー

続いて Pawns フォルダに PhysicsMannyPawn があるので、こちらを自身の Content の方に copy してきましょう。
名前がかぶると面倒なので、私は BP_PhysicsMannyPawn に変更しました。

以下のように BP_ThirdPersonCharacter と並べてみます。

まずここで面白いのが、先程の alwei さんの記事でも触れられていましたが、PhysicsMannyPawn のキャラクターは、Simulate Physics されたオブジェクトと同じように押すことができます。

以下の画像は BP_ThirdPersonCharacter で押していますが、もちろん PhysicsMannyPawn 同士で押し合うこともできます。

どうしてこうなるのか?

Mover のコードを追えていないので詳しいことはわかりませんが、まず PhysicsMannyPawnCapsuleSimulate Physics が有効化されています。

ちなみに BP_ThirdPersonCharacter の方でも CapsuleSimulate Physics を有効にしたとしても、以下のコードがあるためそもそも操作すらできなくなります。

// CharacterMovementComponent.cpp

void UCharacterMovementComponent::TickComponent(
{
    // 略
      
    // See if we fell out of the world.
    const bool bIsSimulatingPhysics = UpdatedComponent->IsSimulatingPhysics();
   
  // We don't update if simulating physics (eg ragdolls).
    if (bIsSimulatingPhysics)
    {

詳細も気になるところですが、まずは「これで物理に反応できるキャラクターが手に入った」ということです。

以下は、Physics Constraint を使ったバネを使ったデモです。
ThirdPersonCharacter の方は、ジャンプして着地してもそのままバネの上に立つだけですが、PhysicsMannyPawn の方はバネの跳ね返りの力でそのまま跳ね上がっています。キーを推して能動的にジャンプはしていません。

ThirdPersonCharacter
PhysicsMannyPawn

このバネは以下のチュートリアルで作成したものです。この人のチュートリアルは物理挙動好きな私にはどれも楽しいです😇
UE4 Jump Pad - using Physics Constraints in Unreal Engine 4 Tutorial How To - YouTube

キャラクターのメッシュが「外部からの力」を受ける

上記で貼った Gif 動画で分かる通り、現状ではキャラクターは跳ね上がった際も設定されたジャンプ (fall loop) アニメーションが再生されています。これを物理の影響を受けているようなポーズにしたいです。

Physical Animation

こちらも Physical Animation を使っているだけです。

Quick Start

Physical Animation Component の追加

ここまでで作成してきた Mover で動く BP_PhysicsMannyPawnPhysical Animation Component を追加します。

Physics Asset の付いた Skeletal Mesh に入れ替える

続いて、Skeletal Mesh の入れ替えを行います。というのも、ここまで使ってきた BP_PhysicsMannyPawn がデフォルトで利用する Mover Example の Skeletal Mesh は Physics Asset が適用されていません。

よって、Physics Asset が付いたものに入れ替えます。(Mover Example の Skeletal Mesh をコピーして、Physics Asset をつけても構いません)
私は ThirdPersonCharacter が利用している SKM_Manny に入れ替えました。

Skeletal Mesh の Collision を調整

上述のドキュメント通りで大丈夫です。

ドキュメントにもありますが、Capsule の Object Type が Pawn であるため、最低限 Pawn は除外する必要があります。

BP に設定を書く

ドキュメントとの大きな違いは Profile を使わず、Physical Animation Data を直接 Make して使っています。
また、基準となる Bone を pelvis にしています。

Physics Asset を見ると分かりますが、pelvis 以下ということは実質全てです。

また、Set All Bodies Below Simulate PhysicsInclude Self は無効にしています。これを有効にしてしまうと pelvis もぐにゃぐにゃになって動けなくなります。

Physics Blend Weight のみ変数化していますが、今回は 0.7 に設定しています。これを 1.0 に近づけるほどラグドールっぽくなります。

後はこれを呼び出すだけです。今回は Begin Play で呼び出してしまいます。

さて、これでラグドールっぽいけど動くキャラクターが手に入りました。

最終確認

ここまででウォータースライダーゲームのジャンプ台の動きが再現できました。(ウォータースライダーはキャラクターのポーズが寝そべっていまので姿勢は違いますが)

ちなみに、ウォータースライダーゲームの能動的なジャンプは、Physical Animation を無効化しています。

終わりに

Physical Animation はダメージリアクション等で使いやすい機能ですが、キャラクターを動かす時に使うと違和感のある動きになってしまいます。

今回はウォータースライダーにいるキャラクターでほぼ動きが無いこともあり、違和感なく利用することができました。

加えて、Mover の Physics Based Character Movement を使うことで、キャラクターがより簡単に物理の影響を受けることができるようになり、 Physical Animation が生かされるようになりました。

余談ですが、最初は Physics Control を使って実現しようとしていたのですが、なかなかうまくいかず断念しました。次は Physics Control も使ってなにかできればと思っています。