VRCでFinal_IKを使う（初心者向け？）

## 注意！！！
この記事のやり方は現在、推奨されません。
2025年現在であればこういう回りくどい事をせずとも「VRC Parent Constraint」で実装出来ます。
しかし、何かに応用が効いたりする可能性もあるのでこういう事も出来るよ、という事で記事はのこしておきます

## 初めに

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


### 本来の使い方

本当に初心者の人が勘違いしたらいけないので載せておきます。

ラグドールの設定サンプル（Full Body Biped IK）

https://twitter.com/ayr_suzu/status/986285883958558725

3D空間でお絵かき　（VR IK）

https://www.youtube.com/watch?time_continue=2&v=HX7hog8RwAk&feature=emb_logo

NPCシステム（Aim IK）

https://booth.pm/ja/items/1660733

## 前提知識

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

* 基本的な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特有のモノ』（アプデで仕様変わったりするので、注意）
* 『実は許可コンポーネントリストに入ってるけど使ってる人がいない特殊ギミック』など、普通の人は触らないようなものばかりです。
* アニメーションオーバーライド等、普通の事がしたい方は他のブログ等を見てください。 -->

## やりたいこと

VRCユーザーが
「Final_IKがセールだ！買え！」「ところで何に使うものなの？(笑)」
と言っているのを見かけたので、何かしらの利用方法の提示。

* Limb IK の導入方法（超特殊構造）
  * オブジェクトの持ち替え
  * Fixed joint を使わないワールド固定

>[完成品prefab](https://superamatou.booth.pm/items/1669926)
>持ち替えとワールド固定（置きなおし可能、エモートスイッチ設定済）


* Aim IKを使ったオブジェクト一括管理

>[完成品prefab](https://superamatou.booth.pm/items/1669811)
>パーティクルライブとかの演出に使えるかも？


* 他の記事等を紹介

### メリット

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

### デメリット

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

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

以前Twitterでまとめたもの（以下リンク）があるので、現在の仕様に合わせて少し調整して記事にしてます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Final IK<a href="https://t.co/dvOepItqcq">https://t.co/dvOepItqcq</a><br>の一部の機能 Limb IK を使い以下を軽量化しましょう。<br>・オブジェクトの持ち替え<br>　　（is activeを使わず持ち替えるのでメッシュが節約できるしアニメーション管理がしやすい）<br>・Fixed joint を使わないワールド固定<br>　　（rigid body を使わないので軽量。）</p>&mdash; スーパー甘党 (@Super_Amatou_VR) <a href="https://twitter.com/Super_Amatou_VR/status/1097135726171312128?ref_src=twsrc%5Etfw">February 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

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

### オブジェクトの持ち替え

早速、以下の通りに Chest（肩）から Right hand（右手）にcubeを持ち替える構造を作っていってください。

#### VR IK

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

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

2019/11/17現在上書きされない設定になってるようです。とりあえず、以下の値に。[^2]

[^2]: IKは上書きされたりされなかったり、時期によって、と言うか、運営の匙加減です。

fix Transformを外す
IK Position Weightを０に
Plant Feetのチェックを外す
Locomotionの Weight を0に
Velocity Factor を0に

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

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

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

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

![FBB IK.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/9c485929-a1f0-fd36-6d8a-40059578194c.png)

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

~~それ以外の設定はデフォルトのままで構いません。~~

こちらも調整するべきかもしれません。が、取り敢えず、ギミックは動くのでギミック部分が出来上がってからIKの調整をする、と言う方針が良いかと思われます。

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を入れると他人視点で同期しなくなってます。 -->

![IK_Execution.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/bc5c11c9-5a84-b339-f451-634921666ce0.gif)

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

#### IK設定用の関節

Armature の外に（つまりボーンの影響を受けない位置に）右クリックcreate emptyをしてGame objectの多重構造を作り

To chest
　∟To right hand

Limb IK root1
　∟Limb IK root2
　　∟OBJECT

といった風にリネームする。（分かりやすいようにこのようなネーミングなだけで、1、2、3とかでも全然OKです）
root2を座標をずらし(0,1000,0)、OBJECTで位置を戻し(0,-1000,0)、関節の長さを設定します。

そして OBJECT の中に右クリックで cube を置き、position(0,0,0)にします

これで動かす cube の設定は終わりです。
続いて肩に追従する時にはどの位置にあるのか、手に追従する時にはどの位置にあるのかを設定していきます

OBJECT を ctrl + D で複製し、出てきた OBJECT (1)　を使って位置調整します。
まずは chest から右クリック、create emptyを二回してGame object を作成しChest(Limb)とChest_IKにリネームする。
そしてさっきの OBJECT (1) を Chest(Limb) の子に置く。

Armature
　∟Hips
　　∟Spine
　　　∟Chest
　　　　∟Left shoulder
　　　　∟Neck
　　　　∟Right shoulder
　　　　∟Chest(Limb)　　←(New)!!
　　　　　∟Chest_IK　   ←(New)!!
　　　　　∟OBJECT (1)
　　　　　　∟cube
そして Chest(Limb) ごと動かし位置調整します。
同じように右手首にも、create empty、リネーム

![Ik.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/f73ad76a-a06c-fa38-fd55-bbb0e58c4e26.png)

Right wrist
　∟Right hand (Limb)
と設定し、位置調整後、OBJECT (1) 　は必要ないので Delete　してください

#### Limb IK

Limb IK をTo chest と To right hand にadd component し、画像のように設定します。

* fix Transformを外す
* bone1　2　3　に Limb IK root1　Limb IK root2　OBJECT　をドラッグ＆ドロップ
* <span style="color: red; ">Target　にTo chestにはChest_IKをTo right handにはRight hand_IKを。
    追記：Chest_IK等Targetに指定するオブジェクトにVRC IK_followerを付ける。</span>
* Avatar IK Goal を　Right hand に（今回は右手なので。左手ならLeft hand で）
* Bend  Modifier を Target に

お疲れ様です以上で設定終わりです。
再生ボタンを押して Limb IK のコンポーネントをON/OFFすると IK が変更されます。
To chest が enable かつ To right hand が disable 状態にあると肩に背負い

![Chst.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/b9eab774-783f-9273-5e33-6ddaf3dc735c.png)


逆だと右手に持ちます

![hand.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/75d97acf-061d-c9db-e7fd-ba8cb3c41ccd.png)

### Fixed joint を使わないワールド固定

先ほど設定した Limb IKのターゲットを none にします。
Limb IKをdisable状態にします

以上です。
Limb IK がenableになった場所にワールド固定されます。
一度ワールド固定するとdisableにしても IK 情報を与える Target が none なので動きません。
なのでLimb IK を多重構造にしておく事で、別途他の Limb IK から手元に引き寄せるようにしないといけません。
置きなおすことが出来ませんが、逆に言えば IK の情報がないというのが複数保存されるので Target が none のLimb IKを複数用意しておくことでワールド固定の箇所を複数個所切り替える等ができます。
ワールド固定する瞬間にワールド固定するゲームオブジェクトの子階層でLimb IKで手元に引き寄せ即IK無効化で再度置きなおしを再現出来ます。
Rigid bodyを使わないのでワールド固定をするオブジェクトにコライダーを含む場合、コライダーがRigid body colliderに変化して挙動が変わったりしないので管理しやすい。

![IK_world.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/ada0b2bd-17f1-25e3-2c20-db1253b49339.gif)


## Aim IKを使ったオブジェクト一括管理

### お借りしたもの

noribenさんのビームライトシェーダーとモデルをお借りしました。
https://noriben.booth.pm/items/1637978

### 完成品チラ見せ

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Aim IKを使ったオブジェクトの一括管理。<br>パーティクルライブとかの演出作成のアニメーション管理が楽になると思います。 <a href="https://t.co/5hQtVXdfqj">pic.twitter.com/5hQtVXdfqj</a></p>&mdash; スーパー甘党 (@Super_Amatou_VR) <a href="https://twitter.com/Super_Amatou_VR/status/1193845636522622982?ref_src=twsrc%5Etfw">November 11, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

完成品prefab
https://superamatou.booth.pm/items/1669811

### 作っていく

Game objectを分かりやすいようにLight Groupとリネームします。
子階層にビームライトを複数個、等間隔に並べます。

#### 下準備

アバターに仕込む場合は、Limb IKの項目と同じように、VR IK,FBB IK,IK Execution Orderを設定してください。

#### ターゲット用のオブジェクト作成

それぞれのビームライトの先端付近になるようにCreate emptyします。それぞれの高さは揃えておいてください
作ったオブジェクトをビームライト自体のTransformの影響を受けないように階層を変えます。

#### Aim IKの設定

IKの設定をする為にCreate emptyして画像のように設定します。
今回は90度向きを変えているビームライトの真上にターゲットが有る為、Axis(1,0,0)です。
Aim Transform,Targetの位置関係に応じて値を変えて下さい。

![Aim_IK1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/460716/c4b75e90-4dcb-733d-1efe-8aa3cdb433fd.png)

## 他の記事等を紹介

VR IKを自前で設定する
<https://qiita.com/TyounanMOTI/items/4a68b9b2123baa867924>

ワールド用のラグドール等の設定値
https://twitter.com/ayr_suzu/status/986285883958558725

海外のVRC向けFinal IKまとめてる方々
https://www.youtube.com/channel/UCgZrhtmeno1qwrQFUQg4J0g
https://www.youtube.com/channel/UCmBh1L02HuuKoWrSXsLhCKw

VRC向けではないが（script使用）丁寧に解説してる記事
https://lowpolycat.com/unity_asset1/

同じくVRC向けではない
http://miyas-maincontents.blogspot.com/2016/11/final-ik.html

## まとめ

### 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を用意することで多脚に対応可能