ぼっちプログラマのメモ

UE4とかUE5とかについて書いたり書かなかったり。

【UE5】UE5からの新機能「Distance Matching」を使ってみよう!(サンプル配布あり)

はじめに

UE5からアニメーション新機能として「Distance Matching」が追加されていました!これは「Characterの動きに合わせてアニメーションの再生速度を調整することで、アニメーションに対しての違和感(足滑りなど)を軽減する」ための機能です。

docs.unrealengine.com


例えば、上図の左側はCharacterが止まる際に両足がジタバタして滑っているように見えます。これはCharacter(ゲーム側)の動きとアニメーションにおける足の動きが合っていないためです。
これにDistance Matchingを適応したのが右側の画像です。キュッと止まるCharacterの動きに合わせて再生速度を早くすることで、アニメーションとCharacter側のズレがなくなって違和感が軽減されています!

また、近づいてくる地面に向かって脚を伸ばすような動きも表現することもできます!

という非常に良い感じの機能なのですが、使い方があまり詳しく説明されていません…。一応公式ドキュメントに「着地時の脚伸ばし」の実装手順があるのですが所々画像がなくて分かりづらかったり、DistanceMatchingを活用しているLyra Starter Gameはサンプルとしては複雑すぎて見るのが正直辛いと思います…。

ということで、DistanceMatchingをシンプルに実装したサンプルを公開しました!(他のUE5でのアニメーション新機能も含めてます)

github.com


このサンプルではストップ時の速度調整をDistance Matchingで行っています。
上記リンク先ではDistance Matching用アセットのセットアップまでは書いていますので、本記事ではそれ以降の手順や設定について説明します。なお、上記サンプルをベースに説明しますので、手元で開いた状態で読むと分かりやすいかと思います!

また、下記スライドをざっくりと目を通していることも前提とします(具体的には、Distance Matching, Anim Node関数、Property Accessの部分)。
猫でも分かる UE5.0, 5.1 におけるアニメーションの新機能について【CEDEC+KYUSHU 2022】 | ドクセル


ステートマシンにStopステートを追加



まずは移動用ステート(Walk/Run)から待機用ステート(Idle)の間に、停止用ステート(Stop)を追加します。まだDistance Matching機能は使わないので、特に凝ったことはせずにサクサクと組んでいきます。

ここまでで「停止時にStopアニメーションを再生」することはできるようになります。しかし、ゲーム側の動きとアニメーションが合わないので脚滑りが発生するはずです。これをDistance Matchingでなんとかしていきます。

Sequence Evaluatorのセットアップ



Distance Matchingを使ってアニメーション制御はSequence Evaluatorノードに登録したAnim Node関数内で行う必要があります。そのため、まずはSequence Evaluatorノードをセットアップしていきます。

  • Sequence Evaluator内で制御するAnimation Sequenceを設定
  • Stopモーションはループ再生しないので、 Should LoopフラグをOFF
  • Distance Matchingで再生制御をするので、Teleport to Explicit TimeフラグをOFF




そして、Distance Matchingを使ったアニメーション制御を実装する AnimNode関数をSequence EvaluatorのOn Updateに紐づけます。既存の関数を紐づけることもできますし、上図のCreate Bindingから新規作成・紐づけを行うこともできます。

Distance Matchingを使った再生速度の制御

※ 以降ノードの説明をしていきますが、手っ取り早くコピペしたい方は以下のリンク先からどうぞ
AnimNodeFunc for Distance Matching | Unreal engine Code Snippet


Characterの停止制御にアニメーション側が合わせるためには、まずその停止位置を予測する必要があります。大変そうに聞こえますが、Distance Matchingのために用意されたPredict Ground Movement Stop Locationノードを配置して、各ピンにCharacter Movement Componentのパラメータを渡せばOKです。べんりですね!


そして、同じくDistance Matchingのために用意された Distance Match to Target ノードに予測した停止位置への距離とStopアニメーションに埋め込んだカーブの名前を渡せばOKです。このとき、DistanceCurveModifierのパラメータを編集していないのならカーブの名前はDistanceで問題ありません。

これだけで!いい感じに!!アニメーションの再生速度を調整してくれます!!!

すごくかんたん、すごい!

DistanceCurveModifierについての捕捉


Rootボーンの移動量をAnimカーブとして埋め込む際に使用したDistanceCurveModifierの各制御パラメータは変更することができます。埋め込まれたAnimカーブが意図したものと異なる場合はこれらのパラメータをいじってみると良いかもしれません。
捕捉終わり


最後に、予測した停止位置にCharacterが到着した(Distance to Matchが0)後は通常の速度でアニメーション再生するようにします。ここで使っている Advance Timeノードがそれにあたります。


なので、上図のように組んだAnimNode関数をSequenceEvaluatorのOnUpdateに登録すると、単純に指定したAnimSequenceを再生するノードになります。


というセットアップをしたのが、今回公開したサンプルに含まれるABP_UE5AnimSystemSampleとそのABPが持つUpdate Stop Anim関数です。上図のパラメータを弄るとCharacterの挙動が変化するので、それに合わせてDistance Matchingの制御がどう変化するのかを見てみると面白いかと思います!

さいごに

こうして記事にすると…文字や画像が多くて難しそうに見えるかもしれませんが…実際にやってみると本当にサクッと実装できて驚くかと思います!
少しの手間でアニメーションの品質を改善することができますので、是非試してみてください!

おしまい!