[Unity] Humanoid の 親指に関する見栄えの問題について [VTuber]

# Unity の親指ってなんかおかしくない？

エンジニアのハマりどころについてのお話。
モーキャプ界隈でよく出る話題、

**『手の形おかしくない？』**

というお話について、何か対策しようというお話。

ゲームであれば、まじまじと手の形を見るということ自体あまりないだろうが、
VTuberが世に出始めたのもあり、バストアップの映像の需要が高まったため、
手を見せることが多くなってきた。

そもそもにして、UnityにFBXをインポートする際に、正確な情報が良く分からなかったり、
エンジニアとデザイナーの中間の問題なせいで、当事者たちが「俺の仕事じゃないし」状態になりやすいという問題がある。

今回正しい情報と推定される情報を載せるのだが、
**誰か正解を持っていたら教えて！**

今回サンプルに出しているモデルは、
UnityちゃんURPモデルになる。© UTJ/UCL


# 先に要点

まず、**Unityの親指の第一関節の角度制限の初期値**がおかしいのではないかという問題。

これだけ書かれてもピンとこない人は、この記事を最後まで見てもらえればよいと思う。

## FBXインポートに気を付ける事

そもそもどんな形でインポートするのが正しいのかというおさらいから。

Mecanim Humanoid についての Unity Blog。
https://blogs.unity3d.com/jp/2014/05/26/mecanim-humanoids/

The T-Stance の項目に、インポート時に必要なTポーズについての仕様が書いてある。
その中でも、親指については以下のようにある。

```Thumbs straight parallel to the ground half way (45 degrees) between x and z axis```

**地面に並行**で**X軸(左右)とZ軸(前後)について45度の角度**に設定する、とある。
上からだとこんな感じ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231914/ed18f9fb-315f-fb45-769a-96774b686147.png" width="300"> 

Tポーズの状態だと各関節の**Z軸回転で折り曲げ**になるので、**親指の爪が真横に見える**。
横からだとこんな感じ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231914/67e60e16-5bdd-9a23-d3eb-7086d5262a62.png" width="500"> 

私自身はエンジニアなので完全に蛇足だが、
モデリング自体はやりやすい自然な指の形で行い、リギング時点で気にするとよいとか何とか。（余計なお世話）


## 角度制限とは？

Humanoid には、角度を設定できる機能がある。

アバターでHumanoidに設定するこれ ↓ のなかの、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231914/b51af949-9788-dba2-aa7b-c636c85579f2.png)

これ ↓　（Configure Avatar - Muscle and Settings の項）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231914/15e86305-1937-076d-5aea-562413b95147.png)


このプレビュー機能で、第一関節の Stretched を最大に開いてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231914/2f5e85ce-8c72-d125-a067-ee1ca3bdbaed.png)

親指は明らかに開きすぎなのでは？
これの角度制限でいうと、**プラス側の値**になる。
角度制限を **-20 ～ 0** に設定してみた場合、以下のようになる。
![hand.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231914/171abb91-2da5-b0e2-e091-55478b3ff148.gif)
自分の親指を動かして見てほしいが、親指の**第一関節は意外と動かない**。
このくらいがまだ自然な値ではないだろうか。

というか、Humanoid の仕様上、**最大値側の値をマイナスにすることができない**。
0 の値でもやや開きすぎてる感もあるが、残念ながら Humanoid の仕様としての限界という事になる。
これ以上はインポート時に何かしらの試行錯誤を試すしかない。


## そもそも Humanoid (Muscle) とは何か？

Unity Humanoid は、人間の骨格を特定のルールで標準化した値を使って人間の骨格を操作する。
それが Muscle と呼ばれるものの値であり、**-1 ～ +1 の値で標準化**され、Humanoid Animation ファイルとして扱われる。

Muscle の値がすべて 0 とは何なのか。
よく見るこれである↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231914/e6eb080e-57f9-ee59-a93c-65d995a7347c.png)
これを中心の値として、プラス、マイナス方向に、それぞれどこまで曲がるかを設定することが出来る。
それが Muscle and Settings を使った角度制限の値となる。

先ほどの項目でも書いたが、プラス側の最大値をマイナスの値に設定できないのは、この仕組みが起因しているようだ。
人間が持っている各関節の中間値はこれ、と定義したのが、この Muscule = 0 と思われ、
この値が共通になっているがために、アニメーションの途中の値が破綻しにくい構造になっている（と思われる）

SDユニティちゃんのような、極端に手足の短いモデルであっても、角度制限の値を調節することで、
似たようなモーションとして再生することが出来るわけだ。

蛇足となるが、Humanoid の .anim ファイルには、FootIKの値も入っているようで、（未検証）
歩いたり走ったモーションが接地する場合に、この値を使って接地していると思われる。（これも未検証）
足の関節の比率が違うモデルの場合は、接地が破綻するはずなのでFootIK機能で調整する必要が発生する。
FootIKとMuscleは直接関係がない（更にこれも未検証）
Humanoid Animation は、基本的にFKなのである。

更に蛇足だが、最大値を0にした場合、プラス方向への値は一切動かなくなる。
当然、0 ～ 0 の制限範囲にすると、Animation でどんな値が来てもその関節は全く動かなくなる。
モーションをマッチングするうえで、0が基準値で、それを跨ぐことはないという考え方のようだ。


## Humanoid を使う理由

当たり前だが、汎用性を持たせるためである。

VRM モデルや VRC モデルが Humanoid である理由はこの辺りが要因で、
モーション編集用ツールを使わず、Unity 上で直接動かす場合も当然 Humanoid で動かしたいわけだ。

そして、**手の見た目変だよね問題にぶち当たるわけ**である。
(手の形がきれいに見えない理由は他にもあるが、
Unity Humanoid の範囲を超えてしまうものもあるので今回は扱わないものとする。)

ガチンコで指の角度を割り当てる方法もあると思うが、
特に親指は、作業者によって一定の角度であることは少ないので、
ガッチリをルール付けでもしておかない限り、
Humanoid 対応モデルとして読み込んでも、残念な見た目になることは容易に想像できる。

ついでに、**手のモーキャプ機材は様々な要因でイケてないことが多く**、
この場合でも残念な見た目になりやすい。

この辺りは別記事にでも書きたいと思っているが、
まあシンプルに**手に関する表現は沼**と言っていいだろう。


## ちょっと気になる点

じゃあ **-20 ～ 0にすれば解決だよね？** と思われるかもしれないが、少し気になる記載がある。
Unity Blog に以下のような記載がある。

```
Muscle range adjustments
By default muscle ranges are set to values that best represent human muscle ranges.
Most of the time, they should not be modified.
For some more cartoony character you may want to reduce the range to prevent arms entering body or augment it to exaggerate legs motion.
If you are creating a Humanoid Rig to retarget MOCAP data you should not modify the ranges since the produced animation clip will not respect default.
```

**殆どの場合は変更しないで下さい**とある。
はて？　これは如何にするべきなのか。
答えは出しようがないのだが、見た目が変なので変えざるを得ない。
変える以上は変えた値に責任をもって対応するだけでしかないだろうか。

親指は2軸で大きく動くし、伸ばしきった値をどこで取っていいのか、
作っていても直観的に正解が分かりにくい。
他の4本の指の場合は、最大値でも伸ばしきるか曲げきるかのシンプルな構造なので、
正解にたどり着くのは容易なのだが。

それに加えて、親指の初期値がおかしいとなると、
"理論上おかしくないと思うが、思った見た目にならない"という状態に陥りやすい。
エンジニアかデザイナーのどちらかが正しく理解していないと、答えが無くハマる可能性は大いにある。

個人的には、親指初期値に関しては、Unityのソフト自体が最初から 0 にしてもらうのが望ましいのではないかと思ってはいる。


# まとめ

取りあえず、
**Thumb 1 Stretched のプラスの値を 0 にしてみろ**

ってことで。
後はウェイト調整で頑張って！（急に丸投げ）

より高みを目指したい方は以下も参考にされたし。

- Unity Humanoid制御に指ロールを追加したい
    - https://qiita.com/mkt_/items/d6dc4ff3846d39b1522d

更に高みを目指したいなら、ブレンドシェイプで連動とかしないとダメだろうなぁ。
肘関節とかも、そうやったほうが早いと聞いた気がするし。

以上