【Unity】Questのハンドトラッキングで特定の手の形を認識して処理を走らせる【Meta XR Interaction SDK】

Unity超初心者です。
ハンドトラッキングでオリジナルのジャスチャーみたいなものを実装するまでの手順を書きます。
ただしほとんど後述する参考記事の焼き直しなので、そちらを見てもらったほうがいいかもしれません。

今回作ったサンプルはGitHubに上げておくのでよければ参考にしてください

https://github.com/SousiOmine/JyankenTrackingQuest

# 参考

https://zenn.dev/ekito_station/articles/hand-gesture-with-movement

https://rightcode.co.jp/blogs/17204

# 環境
Windows 11
Unity 2022.3.22f1
Meta Quest3 (おそらく初代でも動きます)
Meta XR Interaction SDK v64

# プロジェクト作成
Unityで新規プロジェクトを作成
私はUniversal 3Dテンプレートから作りました

作成できたら以下４つのパッケージをUnityのパッケージマネージャーからインポートします
OVR Samplesをインポートすれば全部入ると思います
- Meta XR Core SDK
- Meta XR Interaction SDK
- Meta XR Interaction SDK OVR Integration
- Meta XR Interaction SDK OVR Samples

次にUnityの右下にMetaロゴの通知が出ていると思うのでクリックし
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/3bf931ef-a649-5ec1-e35e-19dd039628fc.png)
「Project Setup Tool」を押します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/b954eedb-30d2-f2f1-b800-b6b9bd3f21d9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/e5e3269b-7341-7cee-53fc-7ffab94c6bec.png)
エラーがたくさん出ているので、Fix AllとApply Allを連打して全部消します。
Unityのビルド設定を開いて、Androidを選んでから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/fc34823e-e294-0627-a7c4-9100733870be.png)
「ターゲットの切り替え」を押します
するとまたエラーが出るので、Fix AllとApply Allを連打してまた全部消します

# セットアップ
ヒエラルキーのMain Cameraを削除します

せっかくですしカメラやハンドトラッキング周りの設定はBuildingBlocksで手を抜きます
ツールバーにあるOculus→ツール→Building Blocksで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/a103f9d4-4050-df2a-1d72-de8e33fc4ae6.png)
こんなのが開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/c0a2b3a6-5548-42f7-938c-0c0a97fd20fe.png)
ここから
- Camera Rig
- Hand Tracking
- Virtual Hands

を追加します
（ただBuildingBlocksで追加できるやつは名前やヒエラルキーの配置が結構変わるみたいです。違うところがあればいい感じに読み替えてください。）

ここで１回ビルドして動かしてみます。

ビルド設定のビルドを押すとQuestにインストールするapkをビルドできます。
ビルドしたapkをadbとかなんかでQuestにインストールし起動すると、このように手の輪郭とUnityの空が見えるはずです。
![672a1863075635ab22b1739551f38bd9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/322a593b-f7f7-007c-7c6a-d1744e51a250.png)

# テスト表示用のテキストを配置
TextMeshProを目に見える位置に配置します。
私は`Canvas/DebugText`に配置しました。
詳細は省略

# グーのジェスチャーを登録
ヒエラルキーで空のオブジェクトを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/dd84e992-f7e3-2f18-6578-40250037ff64.png)
オブジェクトにジェスチャーを１つ１つ登録することでジェスチャーでアクションを起こせるようになります。
まずはグーの形を認識したいので、グーの形をこれから登録する空オブジェクト（ここではGooGesture）を作成しました。
また、以後ジェスチャーは右手で行うものとします。

手の形を設定するファイルを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/1d71e93a-812e-3f92-7785-3155cf966192.png)
プロジェクトで
`作成→Oculus→Interaction→SDK→Pose Detection→形状`とたどると、手の形を設定するShape Recognizerを作成できます。グーの形にしたいのでGooShapeと名付けました。

次にGooShapeのインスペクターで、指がどんな形になるかを設定します。
上から親指、人差し指、中指、薬指、小指になります
これは参考以外にも

https://developer.oculus.com/documentation/unity/unity-isdk-hand-pose-detection/

のShapeRecognizerが参考になると思います。
グーはすべての指を閉じるので、私は以下のように設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/5b9004ca-f9c9-7897-8dde-b7028a8e024d.png)

次に、GooGestureにShape Recognizer Active Stateをアタッチします。
これのHandには
`[BuildingBlock] Camera Rig/[BuildingBlock] Interaction/[BuildingBlock] Hand Interactions/RightHand`を設定します。
（以後[BuildingBlock]表記は省略します)

次に`Camera Rig/Interaction/Hand Interactions/RightHand/HandFeaturesRight`にFinger Feature State Providerをアタッチし、Finger State Thresholdsに各指を設定していきます。
State Thresholdsにアタッチするやつはプロジェクトの`Packages/Meta XR Interaction SDK/Runtime/DefaultSettings/PoseDetection`から持ってきて、画像のように設定してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/8430ed4d-cf47-99a7-538e-068282348721.png)

GooGestureに戻って、Finger Feature State ProviderにhandFeaturesRightをアタッチします
Shapesには先ほど作成したGooShapeを設定します
GooGestureが以下のようになっていれば大丈夫です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/7e9531ff-8431-2b5d-f635-c4f77e08a38d.png)

それでは、グーを認識したらTextMeshProのテキストを変えるようにしていきます
DebugTextにActive State Unity Event Wrapperをアタッチし、Active StateにはGooGestureをセットします
When Activatedには右手がグーになったときの処理、When Deactivatedにはグーではなくなったときの処理を記述します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/43057ba1-bc9f-5aad-dc20-621ed7cecc9b.png)

ビルドしてQuestで起動すると、右手をグーにすると文字が書き換わるはずです！
![857fff8e10548eee7fbc80e459b1c194.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/838ae876-0d64-b2be-64b9-679096fcdf28.png)

# パーも作る
パーも同じようにShape Recognizerを作り設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/2ef95ae8-a87f-a441-6d1f-ef3ecf25e6f6.png)

同じようにジェスチャー用オブジェクトを作成して、DebugTextを変更するようにすると認識できるようになりました
![a478aed3862b88ef8cf13b18ec2d4fc8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/423b4be3-6b1a-7402-b0a3-076c034a83c3.png)

## チョキはうまくいかなかった
小指と薬指を閉じる認識がうまくいかず、チョキを認識させることはできませんでした...

## おわり
後半力尽きてかなり適当になってしまいましたが、何かの参考になれば幸いです