VRCでFinal IKを使う（多脚アバター編）

## 初めに

これはVRChat向けの記事です。
**VRChatにおけるUnity**を前提として書いているため、一般的なUnityとは乖離しているケースが多々含まれます。ご注意ください。

## 前提知識

この記事では以下の知識を前提としています。

* 基本的なUnity操作
* VRC物理学（Fixed Jointによるサブアーム、ワールド固定）
* 筆者の拙い文章を理解する読解力と根気

<!-- * 『Final IK』（サブアーム、多脚など特殊なボーン構造から、変身ギミックに使える小技、ぶれないワールド固定）
* 『Animatorを使った特殊ギミック』（[Toggle props](https://www.youtube.com/watch?v=GHjWF4yflRU)や[Particle toggle](https://www.youtube.com/watch?v=fdUZ-cpGNZ8)を始めとした無理やり状態遷移を作る仕組み）
* 『VRC_StationやIK_follower等のVRC特有のモノ』（アプデで仕様変わったりするので、注意）
* 『実は許可コンポーネントリストに入ってるけど使ってる人がいない特殊ギミック』など、普通の人は触らないようなものばかりです。
* アニメーションオーバーライド等、普通の事がしたい方は他のブログ等を見てください。 -->

## やりたいこと

多脚アバターの脚の制御としてはFixed Jointでの制御がよく使われてきました。
しかし、この手法はHumanoid Rigにおける両足のボーンの動きを多脚用のボーンに伝えているだけに過ぎず、動きがぎこちなくなりがちです。
Final IKを使えばよりリアルな多脚挙動を実現することができます。

### メリット

* IKを使うため、関節がいい感じに曲がってくれる
* Fixed JointやRigidbodyの数を減らせる
  * VRC上でのアバターパフォーマンスの仕様につよい！

### デメリット

* 価格が$90と高い（セール中なら半額程度で買えます）
* 日本語の情報が少ない
* VRCのアップデートで挙動が変わる可能性がある

## Limb IK の導入方法（超特殊構造）

以前Twitterでまとめたものがあるので、以下にリンク貼っておきます。

<https://twitter.com/Super_Amatou_VR/status/1097135726171312128>

Limb（四肢）を制御するComponentのため、本来の使い方ではありません（VRCにありがち）。
これを使う事で従来は手などのボーンに直接格納していたオブジェクトをArmatureの外に出し、浅い階層で管理できるので、複雑なアニメーション作る際などに便利です。

Limb IKを使うことで出来る事として、Qiitaでは以下の内容を記事に書いていきます。

* 『多脚アバターの制御』
* 『サブアームを動かす』
  * 文章量多い為、別記事でまとめます

## 『多脚アバターの制御』

### 注意

筆者は普段多脚アバターを使ってませんし、常時サブアームを付けていません。
しかし、『8本の脚をすべてFixed Joinedで制御している』『Very Poorになるからサブアームを外した』といった会話を聞いたことがあったので、これに対する解決案の一つになればとこの記事を書きました。

こういった少し変わったギミック（VRC物理学）はモデリング等と一緒で微調整に次ぐ微調整が必要となります。
また、こういった機構自体も日夜進歩しているであろう事から、最新の情報はVRC内で先駆者たち直接聞くことをオススメします。

### 使用モデル

今回は[二条阜](https://twitter.com/nizyou2)さんの[「二条式アラクネ＆舞弧ニド」](https://nizyou2.booth.pm/items/1619244)をお借りして８つ足を制御します。

### 下準備

以下ではFinal IKに含まれるコンポーネントを使います。  
未インポート環境ではコンポーネントのリストに出てきません。

シーン上にアバターのプレハブが設置してある前提で話を進めます。

#### VR IK

アバターのルート（Pipeline ManagerやVRC_AvatorDescriptorがあるところ）にVR IKコンポーネントをアタッチします。
Humanoidに適合したアバターであれば、Referencesの欄が適切に設定されるはずです。

すべての項目が埋まっている事だけを確認して、問題がなければ他の項目はそのままで大丈夫です。
VRCに上書きされるので設定は気にしないでいいです。

最後にVR IKコンポーネントのチェックボックスを外しておきます。

![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/74a1821e-f4a1-67e9-b90e-49f47b3b8cca.png)

#### Full Body Biped IK[^1]

同様にアバターのルートにFull Body Biped IKをアタッチします。

[^1]: （以下、FBB IK）

VR IK同様に、Refarencesが埋まっている事だけを確認します。
その際に下図のようにボーンに走っている線が青色になっているかも合わせて確認します。

![キャプチャ8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/010ebe08-0ca3-6d41-5b04-d77788448eff.png)

線に赤色が混ざっている場合、関節どちらの方向に曲がればいいのかFBBIKが認識できてない状態です。
この場合はUnity上で構わないので、膝に微小な角度（0.1度くらい）をつけてあげることで正常な状態（青色）になります。
この際、関節が曲がるべき自然な方向に角度をつけます。

![キャプチャ8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/e7fdcd66-e377-639d-5471-b887119eb555.png)

それ以外の設定はデフォルトのままで構いません。
VR IK同様、FBBIKコンポーネントのチェックボックスも外しておきます。

#### IK Execution Order

同様にアバターのルートにIK Execution Orderをアタッチします。

IK ComponentsのSizeを2にすると、その下に入力欄が2つ出現します。
1つ目の入力欄(Element 0)に**VR IK**を、2つ目の入力欄に**FBBIK**をセットします。
Inspector内のコンポーネント名を直接ドラック＆ドロップでセットできます。

<!-- ~~（そして下で設定していく Limb IKを3番目から順番に入れていきます。）~~
VRCのアプデでここにLimb IKを入れると他人視点で同期しなくなってます。 -->

![キャプチャ7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/01b9f4e5-5416-fd35-532c-12ba20b46a6a.png)

以上の操作でIKの実行順序を設定することで、VRC上での挙動の安定化を図っています。
（これをしないとLimb IKの挙動が安定しません。）

#### ウェイト未割り当てボーンの除去

ウェイトが塗られてないボーンをHumanoidのボーン(UpperLeg、LowerLeg等)に含めてしまうと、以下で追加するLimb IKがうまく動いてくれません。

UnityにおけるHumanoidのConfigureではエラー等は示されませんが、どうやらVRC上ではこれは正常なボーンとして認識されないようです。
ダミーメッシュに当該ボーンのウェイトを設定し、Skinned Mesh Rendererのチェックを外し、不可視にすることで解決します。

また、unity上でボーンのscaleを0にしたボーンも認識しないので合わせて注意です。

（今回は二条さんの協力の下、脚のボーンを分離済みのFBXを用意していただきました）

アバターのルートにあるArmature内に対するIKはVRC上でコンポーネントのパラメータが上書きされ、他人の視点で同期しなくなりますので（←アプデの度に仕様変わりますので注意）、そこは上書きされる前提で多脚部分だけ別FBXに分離してHipsの子供に配置する事で上書き対象から外します。

### 中継地点の作成

Final IKには地面との接地処理を行うための**Grounder IK**がありますが、今回のケースでは以下の理由から採用しません。

* ワールドの（scene上の）コライダーのレイヤー設定が不明瞭
* 背伸びした時に足が綺麗に伸びてくれない

参考として、Grounder IKに関する公式の動画を載せておきます。
英語ですが、どういった挙動かだけでも伝わると思います。

<https://www.youtube.com/watch?v=9MiZiaJorws>

アラクネの足の動きは蜘蛛の脚の動きを参考に真似してみます。
適当に動画等で動きを確認したところ

* 右足一本目三本目と左足二本目四本目が（右足に追従）、前に動く際に
* 左足一本目三本目と右足二本目四本目が（左足に追従）、体を支えるように動かすとそれっぽくなりそうです。

以上から、右足、左足にそれぞれRigidbodyを付けます。
（蜘蛛の脚の方ではなく、Humanoidボーンの足、UpperLeg.RやUpperLeg.Lの方です）

各脚のボーンの末端の位置に合うように脚の分だけ空のGameObjectを作り、アバターのルート（Armatureの外）に設置します。
作成したGameObjectにFixed Joinedコンポーネントを追加し、自動的に追加されたRigidbodyのFreeze Position Yにチェックを入れます。

Fixed JointのConected Bodyは前述の挙動になるよう、交互に設定していきます。

今回のケースでは

* **右足**の1本目と3本目、**左足**の2本目と4本目をUpperLeg.R
* **左足**の1本目と3本目、**右足**の2本目と4本目をUpperLeg.L

に接続しておきます。

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/f9cf016f-c306-c7f2-e510-633dfc199eae.png)![uploading-0]()

これで地面に潜らず、足の動きに連動して動かすための中継地点が出来ました。

### Limb IKをアタッチするGame object群の作成

Armatureの外に（つまりボーンの影響を受けない位置に）空のGame Objectを8つ作ります。
ここではそれぞれをL1, L2, L3, L4, R1, R2, R3, R4とします。

(アバタールート)  
　├ L1  
　├ L2  
　├ L3  
　├ L4  
　├ R1  
　├ R2  
　├ R3  
　└ R4  

Limb IKを上の8つのGameObjectにアタッチします。
各パラメータは以下のように設定します。

* Fix Transforms[^2]: チェックを入れたままにします。

[^2]: Fix Transformsにチェックを付けると関節がいい感じに曲がるよう計算してくれますが、その代わりに追従が若干遅れるので[Limb IK の導入方法（超特殊構造）](## Limb IK の導入方法（超特殊構造）)で紹介したような、モノを持たせる等のギミックの場合には適していません。

* Bone1, Bone2, Bone3: 動かしたい多脚ボーン（L1には左足の前から1つ目の脚、R4には右脚の前から4つ目の脚、のように）を設定します。
* Target: [中継地点の作成](### 中継地点の作成)で作成したGameObjectを設定します。
* Avatar IK Goal: 連動させる脚ごとにLeftかRightを設定します。
Bend Modifier を Targetに設定します。

参考として、以下にL1の場合の設定例を載せておきます。
（オブジェクトの名前がL(1)になってますが、**L1**の場合の設定値です。）

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/2bf5390f-1146-b4d5-f070-290e8c8ee2ff.png)

以上で設定は終わりですが、ここまで読んでも正直よく分からないと思うので~~これで分かる人は本職か元々知ってた人でしょ~~
[boothにsample](https://superamatou.booth.pm/items/1643100)を置いているので、そちらを使って挙動を確認してみてください。

Arachne_IK.prefabが今回の記事の通りに設定したモノです。

Dummy_VRと言うprefabは今回紹介したものに更に[ひと手間](https://qiita.com/TyounanMOTI/items/4a68b9b2123baa867924)加えて完全に制御できていますが、リンク先の記事にもある通りHeadボーンのサイズが0になってくれない、と言う難点を抱えています。

AMATOU_FinalIK_Arachne.prefabはダミーメッシュを入れてない場合のサンプルです。
挙動がおかしい様が確認できると思います。

<!-- AMATOU_FinalIK_Arachne3.prefabは、AMATOU_FinalIK_Arachne3という名前でダミーメッシュ（両足の各ボーン付近にcubeを自動ウェイトで作成したもの）付きのFBXを用意し、それを元に制御してます、が、Dummy_VRの挙動程綺麗に同期しないのでそこはどちらの形式にするかはどういうアバターかによるかと思います。 -->

## まとめ

### IKの実行順序

* VR IK
* Full Body Biped IK
* IK Execution Order

以上のコンポーネントをアップロード前に事前にアタッチしておくことで、IKの実行順序を明示的に指定できる。
事前にアタッチしなかった場合は、VRC上で自動的にアタッチされるが、その場合は実行順序が明示されない。

### なぜIKの実行順序が重要なのか

今回の機構は、以下のロジックに基づいて多脚を実現しています。

1. ダミーのHumanoidボーン（UpperLeg.R, UpperLeg.L）が動く（VR IK、FBBIKによる）
2. ボーンについているRigidbodyを元にFixed Joinedが連動して動く
3. Fixed Jointをtargetに指定したLimb IKが動く

VR IKやFBIKより先にLimb IKが動いてしまうと、上記のロジックが正しく動作せず、動きがぎこちなくなってしまいます。

### IK制御の優先度はVR IK, Full Body Biped IK＞Limb IK

[ウェイト未割り当てボーンの除去](#### ウェイト未割り当てボーンの除去)の補足です。

VR IKやFull Body Biped IKの制御下にあるボーンは、Limb IKで制御できません。  
これについては、以下の記事に詳しく書いてあります。

<https://qiita.com/TyounanMOTI/items/4a68b9b2123baa867924>

## 補足

以下はメモ的なものです。
参考程度に捉えてもらえると。

### ネットワークIK

* 自分以外のアバターは角度情報だけを取得している？

### VRC IK_follower

* VRC SDK内に入っている script
* このコンポーネントを付けたGameObjectのTransformは、Position(0, 0, 0), Rotation(0, 0, 0), scale(1, 1, 1)に上書きされる
  位置調整をしたい場合には親にofset用のGameObjectを挟むと良い
* RigidbodyやIK同様、座標計算をするコンポーネント
  * コンポーネントが非アクティブになっている間は計算が停止
  * 結果として、オンオフするたびに位置がズレる可能性有
* Fixed Joined を使わずに、ワールドパーティクルを仕込むことが出来る
  * こちらが本来の用途、詳しい実装方法は別途紹介
* 手首の子階層に空のGameObjectを設置し、VRC IK_followerを付けることで他者の視点でも同期するようになる
  * 結果、他人視点でも同期するIKのTargetとして利用できる
    * 詳しい実装方法はサブアームの実装方法紹介時にでも解説します。

### Limb IK

* Limb（四肢）の名前の通り、本来は手足を制御する為のモノ
* VR IKなどHumanoidを想定したIKでは2本の脚しか制御できないが、Limb IKは設定したボーンのみを制御するため、それぞれの脚ごとにLimb IKを用意することで多脚に対応可能
* IK Execution Orderのsizeを増やし、Limb IKも入れると他人視点で同期しなくなる