Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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 を使うゲームは分かりやすいんですが首が疲れるので、せっかくなのでコントローラーを使っていきたいと思います。

noitak
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした