はじめに
Oculus Integrationでは、サンプル実装としてUIHelper というPrefabが提供されていて、コントローラーからのレーザーでUIを操作することができました。
Meta XR xxx SDKとなったものでは同様のPrefabが提供されていないようだったので試してみました。
参考にさせて頂きました
環境
Unity 2022.3.16f1
Meta XR Core SDK 60.0.0
Meta Quest2
Meta Quest3
環境構築
- 
Unity Projectの作成
3D(URP)でプロジェクトを作成します - 
Android Platformに Switch Platform
 - 
Package Manager から Meta XR Core SDK を Install
 - 
Project Settings > Oculus の警告、推奨設定を適用

- Fix Allをクリック
 - Apply All をクリック
 
 - 
Project Settings > Player の設定を修正
- Company Name を変更
 - Other Settings > Identification > Override Default Package Name のチェックを外す
 
 
シーン作成
- 
新しいシーンを作成して、Main Camera を削除
 - 
Unity GUI を利用して Text と Button を配置
※ VR向けに Canvas の Render Mode は World Space に設定

 - 
Canvas オブジェクトに対して、Meta QuestのUIインタラクションを処理できるように設定を追加
 - 
EventSystem オブジェクトに対して、Meta QuestのUIインタラクションを処理できるように設定を追加
 - 
レーザーの先のポインターを作成
- 空のGameObjectとしてOVRGazePointer(名前は自由)を作成
 - 空のGameObjectとしてGazeIcon(名前はこの名前でないとNG)を作成し、上で作成したOVRGazePointerの子オブジェクトにする
 - GazeIconの子オブジェクトとして、レーザーの先のポインターとなるオブジェクトを追加
 - OVRGazePointerオブジェクトにOVRGazePointer コンポーネントを追加
 - EventSystem オブジェクトの OVRInputModule コンポーネントを設定
 
 - 
レーザーを作成
- 空のGameObjectとしてOVRPointerVisualizer(名前は自由)を作成
 - 
LineRenderer コンポーネントを追加
- Width の項目でレーザーの太さを調整
 - Materials の項目でレーザーの見た目を調整
 
 - OVRPointerVisualizer コンポーネントを追加
 
OVRPointerVisualizer.csusing UnityEngine; namespace UIControllerLaserPointer { public class OVRPointerVisualizer : MonoBehaviour { [Tooltip("Object which points with Z axis. E.g. CentreEyeAnchor from OVRCameraRig")] public Transform rayTransform; [Header("Visual Elements")] [Tooltip("Line Renderer used to draw selection ray.")] public LineRenderer linePointer = null; [Tooltip("Visually, how far out should the ray be drawn.")] public float rayDrawDistance = 2.5f; [SerializeField] private OVRGazePointer _ovrGazePointer = null; void LateUpdate() { linePointer.enabled = (OVRInput.GetActiveController() == OVRInput.Controller.Touch); Ray ray = new Ray(rayTransform.position, rayTransform.forward); linePointer.SetPosition(0, ray.origin); if (!_ovrGazePointer.hidden) { linePointer.SetPosition(1, _ovrGazePointer.transform.position); return; } linePointer.SetPosition(1, ray.origin + ray.direction * rayDrawDistance); } } } 
実行結果
※ ボタンをクリックした際の処理の説明は割愛します






