Oculus DK2とLeapMotionの頭と指のトラッキングデータをキャラクターのポーズに反映する

#はじめに
この記事では、こちらの作成方法を解説します。
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">Final IK+Avatar hand controller for Leap motionを使用。他、小細工たくさん。&#10;アペンドミクさんでもこの通り。 <a href="http://t.co/6w9bGUO4Bv">pic.twitter.com/6w9bGUO4Bv</a></p>&mdash; afjk (@afjk01) <a href="https://twitter.com/afjk01/status/650346814114107392">2015, 10月 3</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

DK2とLeapMotionのトラッキングデータをFinalIKとAvatar Hand Controllerを使ってリアルタイムにキャラクターのポーズに反映しています。

**必要な有料アセット**
・[FinalIK](https://www.assetstore.unity3d.com/jp/#!/content/14290)(90$)
・[Avatar Hand Controller for Leap Motion](https://www.assetstore.unity3d.com/jp/#!/content/29806)(5$)

**適用可能なモデルについて**
  モデルごとに調整が必要になりますが、MMDモデルであれば大体同じ設定で出来そうです。
  UnityちゃんやKyleなど、各関節のローカル座標がグローバル座標に対し傾いている場合は調整がかなり大変です。

#手順
プロ生ちゃん（暮井 慧）MMDモデルで説明します。
http://3d.nicovideo.jp/works/td8608
##1.MMDモデルをUnityへ読み込む
Stereoartsさんのホームページより、MMD4Mecanimをダウンロードして下さい。
http://stereoarts.jp/
詳細は上記ホームページや書籍の[「主婦ゆに！」](http://www.amazon.co.jp/%E4%B8%BB%E5%A9%A6%E3%82%86%E3%81%AB-%E3%82%82%E3%81%97%E3%82%82%EF%BD%A4%EF%BE%8C%EF%BE%9F%EF%BE%9B%EF%BD%B8%EF%BE%9E%EF%BE%97%EF%BE%90%EF%BE%9D%EF%BD%B8%EF%BE%9E%E7%B5%8C%E9%A8%93%E3%81%8C%E3%81%AA%E3%81%84%E6%96%87%E7%B3%BB%E3%81%AE%E4%B8%BB%E5%A9%A6%E3%81%8CUnity%E3%82%92%E3%81%AF%E3%81%98%E3%82%81%E3%81%A61%EF%BD%B9%E6%9C%88%E3%81%A7%EF%BE%90%EF%BD%B8%E3%81%95%E3%82%93%E3%82%92%E5%87%BA-%E3%80%8C%E4%B8%BB%E5%A9%A6%E3%82%86%E3%81%AB-%E3%80%8D%E5%88%B6%E4%BD%9C%E5%A7%94%E5%93%A1%E4%BC%9A/dp/4798042765)をご参照ください。

Rig>Animation Typeを「humanoid」に変更します（Final IKを適用するため)。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/09b8fb08-982e-c1ce-7735-ba77dd4b7aa4.png)


##2.DK2の向きに頭の向きを追従させる
Virtual Reality Supportedを有効にします。
　メニュー Edit>Project Settings>Player
　Player設定のVirtual Reality Supportedにチェック
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/da8d86a9-cb94-0673-6479-83a94a2eb081.png)

・[HumanoidImitationPack](http://afjk.sakura.ne.jp/data/HumanoidImitation/HumanoidImitationPack.unitypackage)(今回必要なスクリプトやゲームオブジェクトをまとめたもの）をダウンロードし、Assetsへ追加。
・その中のHumanoidImitation.csをSceneに置いたキャラクターに追加。
・HumanoidImitationのHeadにキャラクターのJoint_Headを追加。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/c0bf8a50-610b-21a7-2347-ba51100c389d.png)

これだけでOculus DK2の向きに頭が追従するようになります。
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">Oculus DK2の向きに頭を追従させる <a href="https://t.co/fdVnsVQdXR">https://t.co/fdVnsVQdXR</a></p>&mdash; afjk (@afjk01) <a href="https://twitter.com/afjk01/status/656485445610684416">2015, 10月 20</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

##3.FinalIKを使って頭の位置に姿勢を追従させる
@kikatyanさんのこちらのブログを参考にしました。
[FinalIKを使って頭位置にキャラクターの姿勢を追従させる。](http://machinemaker.hatenablog.com/entry/2014/10/28/203815)

ポイントは、左右の肩のIK Targetの位置を頭の位置から逆算する事です(頭のIK Targetはないので)。
逆算と言っても計算はUnityにやってもらいます。
頭の位置のGameObjectの子として肩のIK Targetを作成しておけば、頭位置の変化に応じて肩のIK Targetも移動します。

3-1.Full Body Biped IKを適用
[FinalIK](https://www.assetstore.unity3d.com/en/?gclid=Cj0KEQjwqZKxBRDBkNmLt9DejNgBEiQAq8XWPiITJ6kndyUJs9grw13-B2FoZouWJrR4js_4aCLQf94aAiyp8P8HAQ#!/content/14290)をAsset Storeよりインポートし、キャラクターのコンポーネントにFull Body Biped IKを追加します。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/c1910329-9f15-566f-b977-df9988337ebc.png)

3-2.BodyIKTargetを適用する
HumanoidImitationPackより、BodyIKTargetをプロ生ちゃんへドラッグドロップ。BodyIKTargetをJoint_Headの位置、LeftSholderTarget、RightSholderTargetを左右の肩の位置に合わせる。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/4bcc637b-6e7f-ec4c-78ca-9c3c425dd8a9.png)


3-3.HumanoidImitationのBody IK TargetへBodyIKTargetを追加
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/5f7cc948-d440-2dda-7634-cc36aea57979.png)

3-4.Full Body Biped IKへ左肩、右肩のターゲット設定
　LeftArm>Left Sholder Effect>
    Target:へ追加
    Position Weight:1
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/b655a721-9f01-2d22-6b7f-716d1caf6bdb.png)

これで、体と頭が連動するようになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/9c4cf884-b901-d7bb-48d0-87f2896078ac.png)
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">FinalIkで頭の位置に姿勢を追従 <a href="https://t.co/fEu4qlDzd0">https://t.co/fEu4qlDzd0</a></p>&mdash; afjk (@afjk01) <a href="https://twitter.com/afjk01/status/656489748316442624">2015, 10月 20</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
##4.LeapMotionの手の位置を反映する
Leap MotionのUnity Core Asset v3.0.0を使用します。
※Asset Storeのものは古いので以下からダウンロードしてください。
https://developer.leapmotion.com/downloads/unity

4-1.自分の手をLeap Motionで持ち込む
・LeapmotionのPrefab　LMHeadMountedRigを追加する。
・Main Cameraは無効化します。
・LeftEyeAnchor、RightEyeAnchorのカメラは無効化し、CenterEyeAnchorのカメラを有効化。
・ClearFlagsをSky boxに。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/e1cce5d3-d874-2654-da51-abe0ecd3f16d.png)

手のモデルはお好みで設定してください。
画像はCleanRobotFullLeft(Right)Handを設定した例。
CenterEyeAnchor>HeadMount>LeapHandController>Hand ControllerのLeft(Right) Hand Graphics ModelへAssets>LeapMotion>Prefabs>HandModelsNonhuman>CleanRobotFullLeft(Right)Handをそれぞれ追加。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/7fa65d9c-934d-0e11-f148-cf97c9b0d743.png)

これで、自分の手を持ち込めました。

4-2.キャラクター用のLeapControlerを追加
Sceneに置いたLMHeadMountedRig>TrackingSpace>CenterEyeAnchor>HeadMount>LeapHandControllerをAssetsへドラッグ＆ドロップしてPrefab化し、このPrefabをJoint_Headの子として追加する。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/8ff49eac-df2a-8e01-cd02-e0f301d88aef.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/b580e044-bc32-b96f-fffc-80e3a702052a.png)
これでキャラクター用のLeapMotionの手が出ます。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/915b36ea-0e04-e4fa-e229-08929e77346a.png)

4-3.キャラクターの手をLeamMotionに追従させる。
HandIKTargetControlスクリプトを使って手のIKTargetを制御します。
まず、HumanoidImitationPack>IKTargetsから、LeftHandIKTarget/RightHandIKTargetをプロ生ちゃんへ追加し、それぞれ左右の手首の位置に配置してください。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/9520249f-831f-9aa1-f02b-4b42182e8fab.png)
次に、キャラクターに追加したLeapControllerへHumanoidImitationPack>Scripts>Hand IK Target Conrolスクリプトを追加します。
画像の通り設定してください。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/73473e01-2deb-c2c6-1d0f-93a597998e7f.png)

4-4.Full Body Biped IKへの手のIK Target追加
Left Arm>Left Hand EffectorへLeftHandIKTargetを追加し、Position Weight、Rotation Weightをそれぞれ1にしてください。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/782af5d6-0c23-dc99-7aee-c506815f1035.png)
Chain>BendGoalには、肘を設定する。これで腕がおかしな方向に曲がるのを防ぐために入れています。
Right Armも同様に設定する。

![image](https://qiita-image-store.s3.amazonaws.com/0/43734/e37aaa11-de75-e4c9-3ee8-d9d2894dc157.png)
これで、Leap Motionの手の位置にキャラクターの手が追従します。
手を伸ばしても肘が伸びきらない場合は、LeapHandControllerのScaleを大きくしてみてください。

>もしもLeap Motionとキャラクターの手の方向がずれていた時は
>Left(Right)HandTargetのRotationを調整して合わせてください。
>![image](https://qiita-image-store.s3.amazonaws.com/0/43734/900d3384-255a-439e-8514-23a06ba5b3e2.png)
>![image](https://qiita-image-store.s3.amazonaws.com/0/43734/caac3a00-ab3c-417d-5723-16e5e5438bad.png)

キャラクター側のLeapMotionの手はもういらないので非表示にします。
LeapMotionControllerから、手のGraphics ModelをNoneに設定。
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/82eba23e-7a3f-a589-2b69-f5ff5a64b0cc.png)

これで、頭と手の追従が完了です。
これだけでも結構楽しいです。
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">LeapMotionの手の位置に追従させる <a href="https://t.co/EdZqr37hco">https://t.co/EdZqr37hco</a></p>&mdash; afjk (@afjk01) <a href="https://twitter.com/afjk01/status/656494026347122688">2015, 10月 20</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

##5.キャラクターの指を動かす
折角なので、ここまで来たら指も動かしたいですね。
[Avatar Hand Controller for Leap Motion](https://www.assetstore.unity3d.com/jp/?gclid=Cj0KEQjwqZKxBRDBkNmLt9DejNgBEiQAq8XWPt1TO1kK1hsHY8hWzixbhAztCT4CF1ZIX9ByzaI1wN8aAsXw8P8HAQ#!/content/29806)をAsset Storeからダウンロードし、インポートして下さい。
このアセットは手の位置も動かすことが出来るのですが、今回は指のみに適用します。

5-1．指用のLeapMotionコントローラーを頭に追加する
・EmptyGameObjectを9.joint_Headに追加する。名前はLeapAvatarHandControllerとでもしましょう。
・ComponentにIK Leap Hand Controllerを追加する。
・デフォルトでは、LeapMotionが水平に置かれている設定になっているので、HMDマウント設定とするため、Rotation x:270 Y:180 Z:0へ変更。
・Spawn Pointには自分自身(LeapAvatarHandController)を設定。
・Avatar Left Hand,Right Handにそれぞれキャラクターの手首(Joint_LeftWrist/Joint_RightWrist)を追加します。

>もしもキャラクターのScaleを1.2等に変更している場合は、手が大きくなってしまうので、逆にLeapAvatarHandControllerのScaleを0.83(=1/1.2)くらいに小さくしてください。

![image](https://qiita-image-store.s3.amazonaws.com/0/43734/ce18bd08-ce5d-9f1e-bfc5-7a3e0e24fdad.png)

5-2.左手にRigged Hand追加
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/710b8e20-b129-572a-a760-1e8c7d62fa38.png)

5-3.各指にRigged Finger追加
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/32d61381-4ca7-8feb-92ea-3baf83f481cf.png)

5-4.Rigged HandのFingersに各指を追加。
順に、
Element 0 - Thumb：親指
Element 1 - Index：人差し指
Element 2 - Middle：中指
Element 3 - Ring：薬指
Element 4 - Pinky：小指
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/447fc824-c1ae-cb91-d907-57efd4dc5686.png)

5-5.各指の設定
画像に従って指のBone、Model Finger  Pointing、Model Palm Facingを設定してください。
Model Finger PointingとModel Palm Facingは指の向きを決めています。
指の向きがおかしい場合はこの値を調整してください。
左手：親指
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/f4966cbe-44e4-091e-a400-1b02c24b7859.png)

左手：人差し指～小指
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/ace37e09-2f90-783f-39f6-53b1df0bf89c.png)

右手：親指
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/39e8485d-b604-8b57-5328-e0fb30be6a13.png)

右手：人差し指～小指
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/bcb77374-746a-100d-3ad9-f638a9fee2e1.png)

これで完成です！
![image](https://qiita-image-store.s3.amazonaws.com/0/43734/0ede24f8-6ce9-6e4a-c560-c5be9d587ebf.png)
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">LeapMotionの指の動きを反映する <a href="https://t.co/JZ2QQ6WqP4">https://t.co/JZ2QQ6WqP4</a></p>&mdash; afjk (@afjk01) <a href="https://twitter.com/afjk01/status/656494239510102016">2015, 10月 20</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

この実行ファイルは[こちら](http://afjk.sakura.ne.jp/data/HumanoidImitation/PronamaChan_MotionTracking.zip
)で公開しています。

ご質問などあれば、Twitter:@afjk01までお気軽にお問い合わせください。
#あとがき
Oculus Connect2で話題となった[「Toy Box」](http://www.roadtovr.com/new-oculus-touch-toybox-videos-show-gestures-sock-puppets-shrink-rays-and-more/)。その説明で触れられた*Shared Presence*を体験したいと思った事がきっかけでこのVRアプリを作成しました。
手軽に試す方法として、まずはキャラクターに自分の動きを追従させてみようという試みです。
Leap Motionは素晴らしいデバイスですが、トラッキングが外れる事が多く、なかなか思ったようにはいきません。
Oculus Touchが発売されたら対応したいですね。