Unity + Oculus Quest2 + ROS2 + 箱庭でロボットを動かす(2/3)

# 概要
TOPPERS/箱庭では，ROS2 で Unity ロボット制御できるようにしていましたが，これが VR 空間上で体験・操作できるようになりました！

ちなみに，こんな感じのことができます！！

https://twitter.com/kanetugu2020/status/1491954460389969920

この体験をいろんな方と共有したく，3 回に分けてインストール手順を説明しています．

* 1 回目：[TOPPERS/箱庭に Oculus でダイブできるにようになる](https://qiita.com/kanetugu2018/items/95c16865b8ed4e2ed974)
* 2 回目：VR 空間で移動してモノをつかめるようになる(本記事)
* 3 回目：[タッチセンサを追加して，VR 空間のロボットを動かせるようになる](https://qiita.com/kanetugu2018/items/9dfbd2cff1ebbc27ba37)

前回は，Oculus を使って，Unityで作られた箱庭VR空間にダイブできるようになりました．ですが，移動することはもちろん，モノをつかむこともできません．

2 回目である今回は，移動とモノをつかめるようにするまでのインストール手順を説明していきます．


なお，今回のトライでは，こちらの記事に助けられました（感謝，感謝）

https://raspberly.hateblo.jp/entry/OculusQuestDistanceGrabberGrabbable#GrabManager

# 手順サマリ
1. 左手を追加する
* 右手を追加する
* モノをつかめるようにする
* レッツ ダイブ！

# 左手を追加する
左手を追加するために，まずは前回作成したキャラクタ(OVRPlayerController)をプロジェクトビューを開いてみましょう．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/0de5d7e3-1e93-9cc0-48f2-0d5cda2f2fb3.png)

上図の「LeftControllerAnchor」が見えます．ここに，左手の部品をD&Dします．

左手の部品は，Oculusのアセットとして以下にあります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/26f6b60b-e6ba-9bfd-d39f-efc0324b6000.png)

それでは，「DistanceGrabHandLeft」をドラッグして，「LeftControllerAnchor」の下にドロップします．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/77ecd8a2-7174-8105-868b-8d326a779e97.png)

このまま使えると良いのですが，実は細かなパラメータ設定が必要となりますので，インスペクタビューを見てみます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/c2e23e06-7112-f87b-f7a6-9faea0b05754.png)

設定が必要となるパラメータは以下です．

* Handスクリプト
  * Animator
     * 「l_hand_skeletal_lowres」を選択
     * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/6c108e6e-65f1-b4e4-995b-4413a3b52298.png)
* OVRGrabberスクリプト
  * Grip Transform
     * DistanceGrabHandLeft配下にある「gripTrans」をD&Dします
     * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/18276a84-fdb4-5d26-f1d7-0c7d69e9485d.png)
  * Controller
     * 「L_Touch」を選択
  * Parent Transform
     * 「LeftControllerAnchor」をD&Dします
  * Player
     * 「OVRPlayerController」をD&Dします

パラメータ設定が終わった状態はこうなります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/e3fdddbf-0a39-b2a2-3a1b-777259901b99.png)


# 右手を追加する
右手が不要な方は本ステップはスキップいただけます．
追加したい方は，同じ要領で右手を追加していきましょう．

追加する場所は，「RightControllerAnchor」です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/cf1193c6-d6a3-2b3e-cc91-940a059bc1f6.png)

右手の部品は，Oculusのアセットとして以下にあります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/9b364b21-ba7a-3c73-a011-cef0607b01c2.png)

「DistanceGrabHandRight」をドラッグして，「RightControllerAnchor」の下にドロップします．

ここで，DistanceGrabHandRightをドロップして，インスペクタビューを見てみると，左手とは違うことに気づきます．左手は「OVRGrabber」がアタッチされてましたが，右手は「DistanceGrabber」がアタッチされています．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/0f5eb992-2a87-a658-8a44-46ef2d1c8ec8.png)

このままでも良いかもしれないのですが，左手と右手を同時にシミュレーションしようとすると，Assertが発生することがわかりました．

今回は両手を使いたいので，これらのスクリプトを外して，左手と同じスクリプトを割り当てることにします．

まずは，DistanceGrabHandRightのprefabをアンパックし，Handスクリプトを削除します．
次に，以下からHandスクリプトをアタッチします．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/ff16284b-60f7-5012-249a-2884a7e702f9.png)

アタッチするとこうなります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/8601604e-7053-e485-2c39-c3d46ea2352d.png)

あとは，左手と同様な手順でパラメータを設定するだけです．
なお，Handスクリプトの「Default Grab Pose」は，以下からD&Dしてください．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/bb372580-35e2-bd4a-d04d-f692e281118a.png)

設定後のパラメータはこうなります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/23304c4f-ce66-eee5-4332-5fcff19ea6b8.png)


# モノをつかめるようにする
Oculusでモノをつかめるようにするには，２つやるこがあります．

* GrabManagerを配置する
* つかみたいモノにDistanceGrabbableスクリプトをアタッチする

## GrabManagerを配置する
GrabManagerを配置するには，その入れ物が必要です．

以下のprefabをOVRPlayerController直下にD&Dします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/739a2528-aab4-19e2-9864-63a07d80d110.png)

こうですね．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/30cb7339-5ee7-0f5e-c14a-5ad9e418f836.png)


DetectGrabRangeのインスペクタビューを開いて，GrabManagerスクリプトをアタッチしましょう．
GrabManagerスクリプトは以下にあります．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/8b6b4412-737c-c8f2-03c9-38f5dc8b1993.png)

アタッチ後の状態はこうです．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/ae0450bd-e0de-8c72-6f38-bc55b74bfd0d.png)


## つかみたいモノにDistanceGrabbableスクリプトをアタッチする
DistanceGrabbable スクリプトをアタッチするモノには， rigidbody と boxコライダが割り当たっている必要があります．

ここでは，事前に用意している以下の黒い「Cube」を使います．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/dcbe8b16-2562-bd73-54cf-c2b9f2fa04e4.png)

DistanceGrabbableは，Oculus のスクリプトとして，こちらにあります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/20a65339-967a-03e1-da15-1a25ea8a7a61.png)

これをCubeにアタッチして，インスペクタービューをみるとこんな感じで見えます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/1a3e549b-cdf6-7c5f-d650-224073a074be.png)

以上で設定は終わりです！！

# レッツ ダイブ！

では，いざダイブです！

ダイブ後，自分の場所がわからなくて，左右を見渡したら，ロボットを確認できました．
目的の場所に移動して，モノをつかめていますよね．

https://twitter.com/kanetugu2020/status/1492330682353614849

なお，移動のオペレーションは以下の通りです．

* 場所の移動：左手のスティック
* 方向転換：右のスティックの左右


# お知らせ：箱庭もくもく会

TOPPERS箱庭WGでは，もくもく会を不定期に開催しています．
本記事の内容を実際に試してみたい方や試してみたけど詰まっている方は，ぜひご参加ください．画面共有しながら参加者同士でサポートしたり，一緒に新しい機能を実装したりと”もくもく”しましょう．

https://hakoniwa.connpass.com/