3Dモデルのボーンは本物の人体より簡略化されている分、現実的ではない動きをしてしまうことがあります。
個人的にはひざの関節の見た目が微妙なのがずっと気になっていました…。
今回は、ひざの関節についてUnityで対策をする方法を試してみたので記事にまとめました。
もくじ
どんな現象なのか
回転の軸が点になっている場合、ウェイトとボーンの動きの関係で90度以上に曲げた時にメッシュが関節ギリギリになって足が短く見えてしまいます。
本来の人間のひざは大きな骨が支点のところにありますが(ひざのお皿)、これを再現するような動きができません。

こういう現象の対策として二重関節や補助ボーンを使って補正をする方法があります。
今回はUnityに持っていくHumanoidリグのモデルを作りたいので、Humanoidリグでも使える補助ボーンを使った補正方法をやってみようと思います。
補助ボーンを作る
まずはBlenderを使ってこの簡易版のひざモデルに補助ボーンを作ります。
UpperLegとLowerLegが親子関係になっていますが、UpperLegの子として新しく補助ボーンを作ります。
接続は切らずにひざの関節から前側に飛び出す形です。
このボーンはUnityのHumanoidリグに読み込む必要がないので名前は何でもいいですが、今回はとりあえずKneeとしました。

これだけだと例としては見づらかったので、膝部分の向きが分かるパーツもつけてみました。

Blenderでの処理は以上でOKです。
このボーンでウェイト塗りをしてFBXでUnityに持っていきます。
補助ボーンを動かす
UnityでHumanoidリグのモデルを使う場合、モデルに含まれている規定以外のボーンは親に追従して動くだけになります。
こういうボーンはコンポーネントやアセット・自作のスクリプト等を使って別途動かすことができます。
今回は「Rotation Constraint」コンポーネントを使います。
Rotation Constraintコンポーネント
コンポーネントをKneeボーンにアタッチします。
Constraint SettingsのSourceに回転のコピー元になるボーンを指定し、Weightに割合を指定します。
今回は半回転させるのが目的なので0.5としました。
設定が出来たらActivateボタンを押します。(初期値を確定させるみたいです)

これで関節を曲げるとKneeボーンが半回転してひざのシルエットがきれいに出るようになります。
こんな感じです!

回転前

コンポーネントなし

コンポーネントあり
スクリプトを自作する
当初コンポーネントの存在を知らなかったので自分でスクリプトを書きました…。
挙動としては変わらないと思います。
これを元にして、回転をイージングと組み合わせたい・別の方向に回したいなどのやり方を作ることができるかなと思うので一応置いておきます。
Quaternionの初期位置の差分を減算することになりますが、QuaAとQuaBの2つのQuaternionがあるときに加算は「QuaA * QuaB」で減算は「QuaA * Quaternion.Inverse(QuaB)」になります。
[SerializeField] Transform target;
[SerializeField] float weight; //回転の追従割合
Quaternion targetQua; //ターゲットのTスタンス時の回転値
Quaternion offsetQua; //ターゲットと補助ボーンの差分
void Start()
{
targetQua = target.transform.localRotation;
offsetQua = target.transform.localRotation * Quaternion.Inverse(transform.localRotation);
}
void Update()
{
transform.localRotation = Quaternion.Lerp(targetQua, target.transform.localRotation, weight) * Quaternion.Inverse(offsetQua);
}
まとめ
注意点として、補助ボーンは「なくても成立するボーン」なのだと思います。
入れなくても見た目がほとんど変わらない、90度より深く曲がらない関節や指などの小さい関節に入れる必要はないかなと…。
個別に動くスクリプトが多くなれば少しずつ重くなります。
僕はひざだけはずっと気になっていたので入れることにしましたが、ひじや他の関節はウェイト塗りでの微調整で済ませることにしました。
関節を深く曲げた時の見た目がとても良くなるので、モデルにこだわりたい方にはオススメです!