0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Meta Quest】XRI対応版ポインターを実装する

Last updated at Posted at 2025-12-12

アドカレ

KENTOのひとりアドカレ13日目の記事です。
https://qiita.com/advent-calendar/2025/kento

環境情報

ツール/SDK バージョン
Unity 6000.0.62f1
Meta XR Core SDK 81.0.0
Open XR Plugin 1.16.0
XR Interaction Toolkit 3.0.9
XR Hands 1.7.1

事前準備は以下の通りです。

デモ

コントローラーでUIにホバーするデモです。Rayの衝突箇所にポインターが表示されます。

2025AdventCalendar16.gif

ハンドトラッキングで3Dオブジェクトにホバーするデモです。こちらもRayの衝突箇所にポインターが表示されます。
2025AdventCalendar17.gif

衝突箇所にポインターを出す

既にRay自体の実装はXRIにあるので、その処理に乗っかる形で実装可能です。ポインターの実装も実はXRIに用意されているのかもしれませんが、見つけられなかったので自前実装を行いました。

using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit.Interactors;
using UnityEngine.XR.Interaction.Toolkit.Interactors.Visuals;

/// <summary>
/// ポインター制御クラス。
/// </summary>
public class PointerController : MonoBehaviour
{
    [SerializeField] private GameObject _pointer;
    [SerializeField] private XRBaseInputInteractor _curveVisualObject;

    private ICurveInteractionDataProvider _curveInteractionDataProvider;
    private Transform _pointerTransform;

    private void Awake()
    {
        _curveInteractionDataProvider = _curveVisualObject as ICurveInteractionDataProvider;
        _pointerTransform = _pointer.transform;
        _pointer.SetActive(false);
    }

    private void LateUpdate()
    {
        if (!_curveInteractionDataProvider.isActive)
        {
            _pointer.SetActive(false);
            return;
        }

        var endPointType = _curveInteractionDataProvider.TryGetCurveEndPoint(
            out var curveHitPoint,
            snapToSelectedAttachIfAvailable: true,
            snapToSnapVolumeIfAvailable: true);

        if (endPointType == EndPointType.UI || endPointType == EndPointType.ValidCastHit)
        {
            UpdatePointerPosition(curveHitPoint);
            _pointer.SetActive(true);
        }
        else
        {
            _pointer.SetActive(false);
        }
    }

    private void UpdatePointerPosition(Vector3 hitPoint)
    {
        var curveOrigin = _curveInteractionDataProvider.curveOrigin.position;
        var directionToHit = (hitPoint - curveOrigin).normalized;
        _pointerTransform.position = hitPoint;
        _pointerTransform.rotation = Quaternion.LookRotation(directionToHit);
    }
}

あとはInspetorで適当に登録して使うだけです。今回のPointerはShpereのスケールを0.1にしたものです。

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?