LoginSignup
40

More than 5 years have passed since last update.

Oculus Goでレーザーポインターを表示する

Last updated at Posted at 2018-05-18

Oculus Go でコントローラーからレーザーポインター的なガイドを表示する方法を調べたので備忘録として。

out.gif

参考

Use GearVrController with Selection Ray - Unity

基本的にここに書かれている通りにやればOK。

使用中のコントローラー(左右どちら?)を取得する

Oculus Go では左右どちらの手でコントローラーを使うか設定できるので、アプリ内での表示もこの設定に沿う必要があります。現在コントローラーを左右どちらの手で使っているかはOVRInput.GetActiveController で取得できます。

// 現在アクティブなコントローラーを取得
var controller = OVRInput.GetActiveController();
if (controller == OVRInput.Controller.RTrackedRemote)
{
    // 右手
    return _RightHandAnchor;
}
else if (controller == OVRInput.Controller.LTrackedRemote)
{
    // 左手
    return _LeftHandAnchor;
}

OVRInput.GetActiveController はStart やAwake のタイミングでは取得できなかった(OVRInput.Controller.None が返ってくる)ので、Update 中で取得しています(ちょっとハマった。素直に参考記事のとおりにすればよかった)。

Oculus 公式のOVRInput ドキュメントによると、OVRInput.IsControllerConnected でも判定できる模様。

コントローラー位置の取得する

コントローラー(手)の位置そのものはOVRCameraRig に付いているLeftHandAnchor/RightHandAnchor から取得できます。

コントローラーのモデルを表示したい場合はOculus Integration に付属のPrefav、TrackedRemote をLeftHandAnchor/RightHandAnchor 以下にそれぞれ配置すると、右手左手の設定に応じていい具合に表示を切り替えてれます。

ovrcamerarig.png

あとはこの位置からRay を飛ばしてレーザーを表示すればOK。

コード

LaserPointer.cs
public class LaserPointer : MonoBehaviour 
{
    [SerializeField]
    private Transform _RightHandAnchor;

    [SerializeField]
    private Transform _LeftHandAnchor;

    [SerializeField]
    private Transform _CenterEyeAnchor;

    [SerializeField]
    private float _MaxDistance = 100.0f;

    [SerializeField]
    private LineRenderer _LaserPointerRenderer;

    private Transform Pointer
    {
        get
        {
            // 現在アクティブなコントローラーを取得
            var controller = OVRInput.GetActiveController();
            if (controller == OVRInput.Controller.RTrackedRemote)
            {
                return _RightHandAnchor;
            }
            else if (controller == OVRInput.Controller.LTrackedRemote)
            {
                return _LeftHandAnchor;
            }
            // どちらも取れなければ目の間からビームが出る
            return _CenterEyeAnchor;
        }
    }

    void Update () 
    {
        var pointer = Pointer;
        if (pointer == null || _LaserPointerRenderer == null)
        {
            return;
        }
        // コントローラー位置からRayを飛ばす
        Ray pointerRay = new Ray(pointer.position, pointer.forward);

        // レーザーの起点
        _LaserPointerRenderer.SetPosition(0, pointerRay.origin);

        RaycastHit hitInfo;
        if (Physics.Raycast(pointerRay, out hitInfo, _MaxDistance))
        {
            // Rayがヒットしたらそこまで
            _LaserPointerRenderer.SetPosition(1, hitInfo.point);
        }
        else
        {
            // Rayがヒットしなかったら向いている方向にMaxDistance伸ばす
            _LaserPointerRenderer.SetPosition(1, pointerRay.origin + pointerRay.direction * _MaxDistance);
        }
    }
}

lp.png

まとめ

ポインター操作にGaze を使うゲームは分かりやすいんですが首が疲れるので、せっかくなのでコントローラーを使っていきたいと思います。

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
40