BLOGブログ

2021.12.01UE4UE/ Animationその他

[UE4] アニメーションを遷移させてプールで泳げるようにする方法

執筆バージョン: Unreal Engine 4.27

みなさん、こんにちは。

前回、[UE4] Waterプラグインを使ってプールを作成するにて作成したプールですが、せっかくなので今回はそのプールを使って泳ぎたいと思います。

今回使用する泳ぐモーションも、前回の屋外プール同様マーケットプレイスから入手する事にします。

○アセットの準備と確認

まずは用意したモーションを確認します。

すると、泳いでるキャラクターの位置が足元になっている事がわかります。

キャラクター用アクターの中心座標が、立っている状態の腰辺りにあることを考えると、泳いでいる状態ではキャラクター自体が足元あたりに移動するという事になり、この点はキャラクターの挙動回りを実装するにあたり色々と考慮する必要があります。

[立っている状態] [泳いでいる状態]

この点を注意しながら実装を進めていきましょう。

○アニメーション側の対応

まずは、泳ぐモーションを再生させるため、アニメーションブループリントを作成していきます。

今回「ThirdPerson」のテンプレートを使っているので、既にデフォルトで用意されている「ThirdPerson_AnimBP」を編集することにします。

AnimGraphには、歩いたり走ったりジャンプのモーションを再生させる「Default」のStateMachineが既に存在していますが、今回はここに新しく、泳ぐ用のモーションを再生させるために別のStateMachineを追加したいと思います。

 

AnimGraph上で右クリックし、「Add New State Machine」を選択します。

 

すると新しいStateMachineが作成されるので、名前をわかりやすく、「Swim」にします。

作成したSwimのStateMachineをダブルクリックで開き、ここで泳ぐモーションに必要なStateを準備します。

今回準備するStateは以下の通りです。

  • プールへの飛び込み
  • 水中での待機
  • 泳ぎモーションの開始
  • 泳ぎモーションのループ
  • 泳ぎモーションの終了

水中での待機から泳ぎへのモーション遷移については、地上での待機→歩行のモーション遷移のようにBlendSpaceを使用することも考えましたが、今回はせっかく泳ぎ開始のモーションがあるため、こちらを使用することにしました。

まずはそれぞれのStateを作成するため、右クリックから「Add State」をクリックし、それぞれのStateを準備します。

Stateが用意できたら、それらのノードを接続し、アニメーションの遷移の流れを組み上げていきます。

「Idle」と「Swim_Start」が双方向になっているのは、泳ぎ始めのモーションが比較的長かったので、泳ぎをすぐやめた際にすぐ「Idle」へと遷移させたかったので、双方向にしました。

Stateの中身はAnimSequenceを呼び出しているだけで、とくにこれといって処理は書いていません。ループモーションにする必要がないモーションに関しては「LoopAnimation」を「False」にしているくらいです。

次にモーション遷移の条件を記述していきます。現在のモーションが終了したら次のStateへと遷移させたい場合は、「TimeRemaining」ノードを使用します。このノードは、現在再生されているモーションの残り時間が取得できるため、残り時間が僅かになった場合に遷移するようにすればよいわけです。

以下の遷移条件が該当します。

  • 「Dive」→「Idle」
  • 「Swim_Start」→「Swimming」
  • 「Swim_End」→「Idle」

次に水中での待機状態と泳ぎ状態を遷移させる条件は、移動速度とします。移動速度に関しては既に陸上での歩きのBlendSpaceで使用されている「Speed」という変数が存在するので、こちらをそのまま使います。

待機状態から泳ぎへと遷移する条件は速度が一定以上になった場合

こちらの条件は以下の遷移条件が該当します。

  • 「Idle」→「Swim_Start」

逆に泳ぎから待機状態へ遷移する場合は速度は一定以下になった場合

こちらは以下の遷移条件が該当します。

  • 「Swim_Start」→「Idle」
  • 「Swim_End」→「Idle」

これらの遷移条件を全て設定できれば泳ぎのStateMachineの完成です。あとはこのStateMachine自体を切り替える処理を行えばよいわけです。

StateMachinを切り替えるために、今回はBlendPosesノードを使用します。ただし、このBlendPosesノードには「int型」「bool型」それぞれの「Enum型」が存在します。これらはそれぞれ引数が違っており、当たられた引数の内容によってアニメーション結果を切り替える事ができます。今回は、CharacterMovementComponentに存在するMovementModeによってアニメーションを切り替えたいので、BlendPoses(EMovementMode)を使用します。

ノードを設置した状態ではDefaultPoseのピンしか存在しません。そのためBlendPosesを右クリックして「Swimming」を選択して、SwimmingPoseのピンを追加して、SwimのStateMachineを繋ぎます。

最後に、CharacterMovementComponentの変数を用意し、そのMovementModeを繋げれば準備は完了です。

あとは初期化時に、CharacterMovementComponentの変数に実際の使用するキャラクターのMoveComponentを設定してあげれば完了です。初期化はEventGraphに「Blueprint Initialize Animation」関数を追加します。

 

○レベル側の対応

アニメーション側の設定が完了したので、今度はキャラクターがプールに入水した際に、移動モードが泳ぎの状態になるようにレベル側を設定する必要があります。そこで今回設置するアクターがPhysicsVolumeになります。

PhysicsVolumeには「WaterVolume」というパラメーターがあり、これをTrueにすれば、ボリューム内に侵入したキャラクターの移動モードが泳ぎの状態になるわけです。ちなみに「FluidFriction」の数値を変更するで、水中での摩擦、つまり水の抵抗を変更することができます。

さっそくプールにこのPhysicsVolumeを設置したいと思いますが、ここで問題になってくるのが最初に確認した泳ぎ状態でのキャラクターの座標問題です。プールの中にそのままPhysicsVolumeを設置した場合、キャラクターは水中用のモーションへと無事遷移できますが、そうなると実際のキャラクターアクターの足元の座標はプールの底になり、キャラクターのメッシュはプールの底へと埋まってしまいます。

  

 

CharacterMovementComponentのSwimmingカテゴリにある「Buoyancy」で浮力を操作する事ができるため、PhysicsVolume内に侵入したら浮くようにしてあげる事も可能ですが、上半身分浮かせる必要があるため、浮力のパラメーターのみで調整するのはかなり厳しそうです。そこで対策としてPhysicsVolumeをプールの水上にもマージンを持たせて囲い、必要であればプレイヤーのみをBlockするようなBlockingVolumeをプールの水中に配置するなど行います。

そうして調整を行って出来たのがこちらになります。

うまくプールに入水すると泳ぎの待機モーションへと遷移し、キャラクターの座標もちょうどよい位置になりました。

しかし、気になるのが、プールに入水するときモーションです。本来の入水モーションに対して、一つ前の走りのモーションとの補間がかなり急に入っているため、とても素早い動きになって違和感があります。そこでStateMaschineの切り換えのモーションブレンドの時間を少し長めに取ることにします。

これにより完成した泳ぎがこちらになります。

無事気持ちよくプールを泳ぐ事ができました。だたこれだけだとちょっと物足りないですね。動きによって波が立ったり水しぶきがほしいところです。

次また機会があればその辺りにも挑戦したいと思います。その時にはWaterプラグインもEXPERIMENTALが取れて正式なものになっているとよいのですが…