UnityでQuest向け開発　動いて、コントローラでUIのButtonを押したい

以下のような状態を目指します。
・自分が動くことができる
・コントローラーが表示されている
・rayでUIにinteractすることができる
![exp_PlayerController.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/30a131a4-95ff-7c4c-c2c6-ad6c61bcfd62.gif)

たぶんこれが一番早いです
# 環境
Unity 2021.3.29
- **Meta XR Core SDK** 68.0.3
Quest向けに開発するSDK
- **Meta XR Simulator** 68.0.2
UnityのGame上でVRの動きを確認できるシミュレーター
- **Meta XR Interaction SDK** 68.0.0
インタラクト系のSDK

実機：MetaQuest3


# コントローラーの設定
・**OVRPlayerController**をシーンに追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/56925d09-2688-6ac0-ef1d-453000c71c0a.png)
プロジェクトウィンドウ内で検索する時はSearch範囲をIn Packagesにしないと出てこないので注意です。
とりあえずこれだけで、動くことができるようにはなります。
でもコントローラーが表示されないのでUIへの接触ができません。

・次に**OVRInteractionComprehensive**を、先程追加したOVRPlayerController直下に置きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/6a5f03c2-5fe8-3f83-5fbe-04b6baefef00.png)

Hierarchyではこんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/5e86994a-8b77-5b85-7d41-8c3817fd9c90.png)

・OVRInteractionComprehensiveを選択すると、OVR Camera Rig Refコンポーネントがあることが確認できます。
Ovr Camera Rigの項目に、OVRPlayerController内の**OVRCameraRig**を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/70b5b0ae-a545-a251-9eb3-d7c52b9a5a36.png)


rayの位置とか微妙に違うけどデフォなので気にしません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/be4f9756-74ad-9ec6-c784-9f73c4a39577.png)

これでコントローラー側の設定は終わりです。

# UI側の設定
今から説明することは、Meta XRInteraction SDK内に含まれているFlatUnityCanvasゲームオブジェクトと構造が全く一緒なので、動き確認などしたい方はこちらを参照することをおすすめします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/62eb62f0-6927-a40e-31ef-05e1f6a384ff.png)



・まずいつものようにHierarchyにButton UIを追加します。
この記事ではこれを"Canvas"オブジェクトとネームしておきます。
・Render Modeを**World Space**に変更します。
・Event CameraにはOVRPlayerController > OVRCameraRig > TrackingSoace > **CenterEyeAnchor**を入れておきます。
・"Canvas"オブジェクトに**PlaneSurface**コンポーネントを追加します。
こんな感じになるはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860179/6f540948-1bad-a585-747e-aecbc7ae8e9c.png)



・次に"Canvas"オブジェクトの**親に空のゲームオブジェクト**を追加します。
ここでは"StartMenu"とリネームしております。
・親の"StartMenu"には**PointableCanvas**と**RayInteractable**コンポーネントを追加します。
・RayInteractableコンポーネントの**Pointable Element**にStartMenu（自身のGameObject）を設定します

・次にStartMenuの直下に空のゲームオブジェクトを追加して"Surface"とリネームしておきます
・"Surface"オブジェクトには**Clipped Plane Surface**と**Bounds Clipper**コンポーネントを追加します。
・Clipped Plane Surfaceの**Plane Surface**にはCanvasを、**Clippers**にはSurfaceを入れます。

概念図としては以下のような感じになります。
■Startmenu（ゲームオブジェクト）
　・Pointable Canvas（コンポーネント）
 　・Ray Interactable
　■Canvas
 　　・Canvas
   　　・Canvas Scaler
     　　・Graphic Raycaster
       　　・Plane Surface
         　　■Button（ここはいじってないので説明省略）
         　■Surface
          　　・Clipped Plane Surface
            　　・Bounds Clipper

Plane Surfaceだけの状態ではUIの接触範囲がPlane上に無限に広がってしまうんです。
それをSurfaceゲームオブジェクトに追加したClipped Plane SurfaceとBounds ClipperでUIの接触範囲をクリップ（＝制限している）したってことです。

## 参考
公式のマニュアルが分かりやすかったです。
ただし英語なので翻訳ツール推奨。
https://developers.meta.com/horizon/documentation/unity/unity-isdk-use-ray-with-ui?locale=ja_JP

日本語解説ならここが分かりやすかったです。
https://tks-yoshinaga.hatenablog.com/entry/quest-dev-ui