BLOGブログ

2015.09.10UE4UE/ Animation

[UE4] Foot IK で段差がある地形でも自然なアニメーションを実現する ~アクターZ値補正~

こんにちは。ほげたつ(@HogeTatu)です。

前回に引き続き、Foot IKについて書いていきます。

今回は 立っている場所よりも低い位置に足を着こうとすると浮いてしまう 問題に対する対応です。

 

LineTrace用のソケットを追加

LineTraceを用いて足と地面との距離を検出するため、スケルタルメッシュにソケットを追加します。

今回はテンプレートでお馴染みのUE4マネキンに対して追加してみます。

  • ball_l ボーンに対して LeftFootSocket を追加
  • ball_r ボーンに対して RightFootSocket を追加

FootIK_03

 

 

キャラクターのカプセルコリジョンサイズを変更

キャラクターが重力がある空間に立っている時、全身を覆うカプセルコリジョンの当たり判定結果から立ち位置を決めています。

つまり何もしなければ、カプセルコリジョンが覆っている空間よりも下に足を伸ばすことができません。

これが浮いてしまう問題の原因です。

前回からの引用です。

前回執筆時点ではコリジョンとメッシュの位置関係を可変にするという方針でいましたが、今回はそもそものコリジョンサイズを変更しておくことで対応します。

以下のように、コリジョンサイズを膝丈くらいまでに縮小します。

FootIK_04

 

高さ補正用の関数(UpdateActorLocationZ)を追加

コリジョンサイズを変更したことにより、このままでは膝下が地面にめり込んでしまいます。

そのため、コリジョン下から各足のソケットに対して LineTrace し、アクターの高さを補正してあげます。

この関数は Tick イベント内から毎フレーム呼び出します。

以下に関数の全体図を記しますが、大きな関数なので細かく分けて説明していきます。

FootIK_05

 

変数一覧

使用されている変数を、名前、説明、デフォルト値の順序で記します。

 

クラスメンバ変数

InterpSinkingDistance アクターZ値補正用のめり込み長さ 0.0

 

ローカル変数

LeftFootSocket 左足トレース用ソケット名 LeftFootSocket
RightFootSocket 右足トレース用ソケット名 RightFootSocket
DeltaSeconds_ 経過時間(引数からノードを繋ぐと煩雑になってしまうため保持) 0.0
CapsuleLowerLocationZ カプセルコリジョンの終端位置(Z値が最も小さい位置) 0.0
HitOffset トレース処理ヒット時の終端位置からのZ値オフセット 0.0
SinkingDistance トレース処理ヒット時のめり込み長さ 0.0
LocationInterpSpeed 徐々に高さ補正の値を変更するための係数 50.0

 

上昇中は更新しない

ジャンプ等で上昇する時には補正は必要ありません。

FootIK_06

 

カプセルコリジョンの終端位置を取得

接地位置検出のための LineTrace は、カプセルコリジョンの終端位置(Z値が最も小さい位置)から開始するため、カプセルコリジョンのワールド座標から半分の高さを引いてローカル変数に保持しておきます。

FootIK_07

 

両足のトレース処理

カプセルコリジョンの終端位置から、各足のソケットに対して LineTrace を実行します。

地面を検出できたら HitOffset(終端位置からのZ値オフセット)、SinkingDistance(めり込み長さ)が取得できるので、よりZ値が低い方(HitOffset が低い方)を採用してめり込み長さを算出します。

FootIK_08

TryFootTrace

FootIK_09

TraceFromLocation

FootIK_10

 

めり込んだ分の高さを補正

地面にめり込んだ分の高さをアクター位置に足してあげます。

補正値が大きいと画面の切り替わりが大きくて良くないため、FInterpTo で徐々に補正値を変更していきます。

また、カプセルコリジョンサイズを変更した都合上、ジャンプから着地する時に歩きに切り替わらない問題があるので、着地時は SetMovementMode して歩きに変えてあります。

FootIK_11

 

結果

FootIK_12

FootIK_13

しっかりと高さの補正ができています。

これであとはもう片方の足がめり込んでいる問題を IK で解決できれば問題なさそうです。

ではまた次回。