＄2-2「Leap Motion（ハンドトラッキング）とHMDを使ったインタラクティブなアプリ開発する」【ヘッドマウントディスプレイとUnityでVRとかMRの開発をやってみる．】

#はじめに

VRやAR開発をしていく中でオブジェクトとのやり取りをもっと簡単にできないかと思いまして，研究室に眠っていたLeap Motionを使って色々試作するためのメモ書きです．前回はとりあえず動作確認を行いましたので今回は実際にシーンを作っていきます．



環境一覧
[SteamVR](https://store.steampowered.com/app/250820/SteamVR/?l=japanese) 1.16.10
[Unity](https://unity3d.com/jp/get-unity/download) 2019.4.27f1 or 2020.1.17f1（動作確認済み，非対応なSDKあり）

[SteamVR Plugin](https://assetstore.unity.com/packages/tools/integration/steamvr-plugin-32647) 2.7.3
[Vive SRanipalRuntime Plugin](https://hub.vive.com/en-US/download) 1.3.2.0


追加アクセサリー
[VIVEトラッカー2018](https://www.amazon.co.jp/dp/B0748ZY323/ref=cm_sw_r_tw_dp_QDZSM4A3844PSM33DB3R?_encoding=UTF8&psc=1)
[Ovrvision Pro（ステレオカメラ）](https://www.amazon.co.jp/dp/B01N7H8YUM/ref=cm_sw_em_r_mt_dp_6TGRDF5BWQPW2PJ1H4WN)
[Leap Motion](https://www.amazon.co.jp/Leap-Motion-Controller/dp/B075T4MH77/ref=asc_df_B075T4MH77/?tag=jpgo-22&linkCode=df0&hvadid=342463500927&hvpos=&hvnetw=g&hvrand=13721783060484696807&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009320&hvtargid=pla-945077929421&psc=1)


使用PCスペック
インテル® Core™ i7-7700K
NVIDIA GeForce GTX 1070

- **環境作成編**

 #1 [Unityのセットアップをする](https://qiita.com/RyoyaHase/items/5a173b7acbdf9aa2cfff)　2021年 1月更新

 #2 [プロジェクトを作ってみる](https://qiita.com/RyoyaHase/items/7b2148e9034584db7420)　2021年 1月更新

 #3-α [Unity2019でVR開発のための環境を整える（SteamVR Plugin2.7.Xをインストールする）：推奨](https://qiita.com/RyoyaHase/items/36910ec8a0b3d8122f8c)　2021年 6月更新

 #3-β [Unity2020でVR開発のための環境を整える（SteamVR Plugin2.7.Xをインストールする）](https://qiita.com/RyoyaHase/items/b7b5f8a7110810c1c0f1)　2021年 5月更新

 #3-おまけ [UnityでVR開発のための環境を整える（SteamVR Pluginの最新版をインストールする）：非推奨](https://qiita.com/RyoyaHase/items/f8b4fb5b04d9f02aae49)　2021年 2月更新

 #4 [SteamVRのダウングレードと自動アップデートの停止（上級者向け）](https://qiita.com/RyoyaHase/items/0dab278b080f517032a0)　2021年 5月更新


- **コントローラの入力やトラッカー，HMDの位置座標，回転座標を得る＋α**

 #5 [VIVEコントローラのボタン入力を取得する](https://qiita.com/RyoyaHase/items/89ffc9d134b784b8ae50)　2021年 2月更新

 #6 [トリガーの押し具合やトラックパッドの位置情報の入力を取得する](https://qiita.com/RyoyaHase/items/81fa026f68aee02fa5d4)　2021年 2月更新

 #6-おまけ [VIVEコントローラを使った開発をする時のおすすめ設定（独断と偏見）](https://qiita.com/RyoyaHase/items/d622e1bb0e345cf78f4f)　2021年 5月更新

 #7 [ヘッドマウントディスプレイとコントローラの位置座標と回転を取得する](https://qiita.com/RyoyaHase/items/325e7250c01f47e7e63b)　2021年 2月更新

 #8 [VIVEトラッカー2018を有効化してUnity上で位置座標と回転を取得](https://qiita.com/RyoyaHase/items/015bbb8671833ef8e740)　2021年 5月更新

 #9 [VIVEコントローラの振動機能を開発してみる](https://qiita.com/RyoyaHase/items/0690761fed2e71f6d517)　2021年 4月更新


- **VIVE Pro Eyeのアイトラッキングを使ってみる**

 #10 [VIVE Pro Eyeの視線トラッキングを有効化（セットアップ）する](https://qiita.com/RyoyaHase/items/024f3589547d1af84a92)　2021年 4月更新

 #11 [VIVE Pro Eyeのアイトラッキングを使ってUnity上で瞬きや視線のデータを取得する](https://qiita.com/RyoyaHase/items/5af948666a039d48a68d)　2021年 4月更新

 #11-おまけ [VIVE Pro Eyeのアイトラッキングで計測できるデータについて（適宜更新）](https://qiita.com/RyoyaHase/items/044826488e763f896a0f)　2021年 4月更新


- **VIVE Pro Eyeのカメラを使ってみる**

 #12 [VIVE Pro Eyeのフロントカメラの解像度（性能）とAR機能を有効化について](https://qiita.com/RyoyaHase/items/853938ec7c8745ec811c)　2021年 5月更新


- **小技**

 [プレイエリアの境界線（シャペロン境界）が表示されないように設定を変更する](https://qiita.com/RyoyaHase/items/57296d7753877afc6f34)　2021年 6月更新

 [Unity上でカメラを複数台追加してHMDやコントローラの動きを見る](https://qiita.com/RyoyaHase/items/4b4733503d53c8387db4)　2021年 6月更新


- **Ovrvision Pro（ステレオカメラ）を使ってAR開発してみる**

 ＄1-1 [Ovrvision Pro（ステレオカメラ）のセットアップをして実際に動かしてみる](https://qiita.com/RyoyaHase/items/262ad2133ee89d00b3cb)　2021年 6月更新

 ＄1-2 [Ovrvision Pro（ステレオカメラ）とHMDを使ってARアプリ開発する](https://qiita.com/RyoyaHase/items/4abcd90f0f2319c89114)　2021年 6月更新

- **Leap Motionを使ってハンドトラッキングしてみる**

 ＄2-1 [Leap Motion（ハンドトラッキング）のセットアップをして実際に動かしてみる](https://qiita.com/RyoyaHase/items/6891c21c8c21dcb08b2f)　2021年 6月更新

 ＄2-2 [__Leap Motion（ハンドトラッキング）とHMDを使ったインタラクティブなアプリ開発する（この記事）__](https://qiita.com/RyoyaHase/items/b0f6cd1d7474286f99ed)　2021年 6月更新

- **アプリを作ってみる**

  [VR（仮想空間）上に曲面ディスプレイを作成して大画面で広角WEBカメラ映像を見る](https://qiita.com/RyoyaHase/items/cc57e67799c1b14ef15d)　2021年 5月更新

今回の記事では，

1．Leap motionをVR用に設定する．
2．HMDに合わせてLeap motionの位置合わせを行う．
3．物体とのインタラクションを有効化する．
4．物体との当たり判定をプログラムする．

という流れ．

#1．Leap motionをVR用に設定する．

いつも通りStemVRPluginを入れたプロジェクトでシーンを作成し，デフォルトのカメラを削除します．
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/a13483c0-08dc-9157-2fd2-67cc2690d6c5.png)

"SteamVR→Prefabs"の[CameraRig]を追加します．
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/c748774d-a3d0-ca82-d7de-173ff98a2729.png)

次にLeap motionの位置をHMDに合わせるために，"Plugin→LeapMotion→Core→Scripts"フォルダ内のLeapXRServiceProviderを[CameraRig]内のCameraオブジェクトに追加します．
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/c4d006ba-db42-b84d-ae09-ffd3eefe8cc3.png)
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/9eb91d2d-55b4-1ca4-a0f8-4f164df13cf1.png)

LeapXRServiceProviderのEdit Time PoseがHMDに取り付ける用の設定にデフォルトでなっています．
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/cfa2b9e0-89e2-7b19-f906-22b6d113fdae.png)

次に手のモデルを追加します．今回はサンプルに切り替えのスクリプトがついてるモデルがあるので，"Plugin→LeapMotion→Modules→Hands→Example"フォルダ内のHandBindingというサンプルを開いてLeapHandControllerをコピーします．
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/243cf19e-8a47-6199-3726-65151d1cd2b1.png)

ペーストで先ほど自分で作ったシーンに追加します．
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/514bc8c5-c278-a67c-7fe2-339f98896131.png)

LeapHandControllerにLeap motionの位置指定用のLeapServiceProviderが入っているのでRemove Componentで削除します．
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/c3dac314-151e-40d4-e7a4-b15851b330be.png)

コンポーネントが無事削除されました．
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/04cbeccf-f328-b9d1-ebde-5dbee6963c8b.png)

これでキーボードの左右の矢印ボタンでハンドモデルが切り替わるようになりました．
![10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/ce774934-483f-1377-8ff6-fa16b3a6c0a3.gif)

ちなみにLeapHandController内のHandModelManagerの各項目ごとにハンドモデルが指定されてるのでここを自作のものに置き換えることをもできます．
![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/c43904b6-7730-d9dc-f15c-62b351c8b155.png)

#2．HMDに合わせてLeap motionの位置合わせを行う．

使っているHMDや貼る場所によって位置や向きが変わるので位置合わせを設定から行います．
先ほど[CameraRig]内のCameraオブジェクトに追加したLeapXRServiceProviderの設定にAdvanced Optionsがあるので展開します．
![10-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/ca974aa1-474c-9d8e-5204-ca4ea4afe7f2.png)

展開したらDevice Offset ModeをManual Head Offsetに変更します．
![10-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/3923ff9c-08e6-1d58-1095-827880da3efb.png)

そうすると奥行，高さ，回転の設定が出るので，自身の環境に合わせて変更します．
![10-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/41eb7646-ab1c-1a5c-136f-40b227aa83e3.png)

自分の環境だとステレオカメラの下側にLeap motionoを張り付けています．
![DSC_0297.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/bd8beade-7943-4db8-1870-78be11e5905b.jpeg)

なので若干手前の下，下向きに回転させて調整します．実行しながら適当に合わせてください．
![10-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/609c6efe-9b46-9038-a6b7-8e003ed33a9c.png)

#3．物体とのインタラクションを有効化する．

インタラクションもサンプルに設定されているものがあるので"Plugin→LeapMotion→Modules→Module→interctionEngin→Example→1.IntractionObject"フォルダ内のIntractionObjectシーンを開きます．シーン内にあるIntractionManagerをコピーします．
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/209dd4e4-cf6c-f4ee-0c0a-9b4877d6b0dd.png)

コピーしたIntractionManagerをペーストでシーン追加します．
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/183c275a-439f-cc7e-d987-a88cc9b547af.png)

今回は見やすいようにするために部屋と机を適当に配置します．これは環境によって変わる部分なので目の前にCubeを置くだけでも大丈夫です（物が置けて手が届けば）．
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/4275c6ae-debd-417c-9410-8f16f0640418.png)

今回は3DオブジェクトのCubeを机の上に新規作成します．物体は当たり判定があればなんでも大丈夫です．
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/7e1c3a8a-010f-cd23-5db7-185be8eb5c24.png)

追加したCubeを選択し，Add Componentを押します．
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/010dcaca-ceb8-2520-9b19-9e4ec3a0a75a.png)

ComponentのPyusicsを開きます．
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/c4959fae-4c1f-8b14-bb21-d93d328fce1e.png)

Pyusicsの中にある，Ragidbodyを選択します．これでゲームオブジェクトを物理特性によって制御する事ができます．
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/cfbdb2a3-d992-08d4-d430-0078b8707404.png)

次に，"Plugin→LeapMotion→Modules→Module→interctionEngin→Scripts"フォルダ内のinterctionBehaviourをドラックアンドドロップでCubeに追加します．
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/7efd9038-7fbb-6f12-933f-0d4d797b1e99.png)

この状態で実行するとCubeを持ったりつかんだりできます．
※この時カメラオブジェクトのCullingMaskがEverythingじゃないとインタラクションに対応させたオブジェクトが正しく表示されません．
![19.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/dd973c7c-0556-4f05-6375-891caf53a370.gif)


#4．物体との当たり判定をプログラムする．

今回はHandCollisionというスクリプトを作成します．
OnCollisionStayという関数は追加したオブジェクトが何かに衝突したときに実行され，collisionに当たった物体のgameObjectなどが返ってきます．
そして今回は机の上にCubeを置いているため常にCubeとの当たり判定が発生するのでDebug.Logが実行されないようにしています．

```C#:HandCollision.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HandCollision : MonoBehaviour
{
    

    void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.name != "Desk")
        {
            Debug.Log( collision.gameObject.name);
        }
    }


    // Update is called once per frame
    void Update()
    {
        
    }
}

```

作成したスクリプトを先ほど作成したCubeに追加します．
![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/eb309e38-4bd9-71e8-7904-39419c29db55.png)

一応指か掌かが判別できます．これを使ってインタラクションするプログラムを組み込むことができます．
![23.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758746/8f9a0721-ac17-368d-d776-7192cb1ab82e.gif)

次回は手と指先の位置データを抜き出します．