しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

HoloLens で Unity の Button を注視したら視線位置にカーソルを表示させてみる

※ これは 2016/05/31 Unity HoloLens Technical Preview ver.5.4.0beta14(Windows版) 時点の情報です

最新版では動作が異なる可能性がありますのでご注意ください

前回 は Button に対して Collider を指定することで視線が当たっているかどうかを検出することができました

ただ、本当にあたっているのかよくわからないので、視線が当たった場合にカーソルのようなものを表示するようにしてみます

とりあえずカーソル用に 3D モデルを用意

f:id:matatabi_ux:20160621184745p:plain

Blender という無料のソフトで「×」という文字を立体にしてモデル化しました

これを fbx というファイル形式で Unity プロジェクトの Assets フォルダの中にエクスポートします

f:id:matatabi_ux:20160621184913p:plain

モデルを読み込んだら1つ GameObject でくるんでこのモデルを Hierarchy にドラッグドロップしました

見かけの大きさや Button より前面に表示されるように Transform の各種値を調整していたりします

いったんスクリプトに戻って VRUI.cs を修正

using UnityEngine;
using System.Collections;
using System;
using UnityEngine.UI;

public class VRUI : MonoBehaviour
{
    /// <summary>
    /// ボタンのラベルテキスト
    /// </summary>
    [SerializeField]
    private UnityEngine.UI.Text buttonLabel;

    /// <summary>
    /// ターゲッテイング用カーソル
    /// </summary>
    [SerializeField]
    private GameObject cursor;

    /// <summary>
    /// 初期処理
    /// </summary>
    public void Awake()
    {
    }

    /// <summary>
    /// 定期的な処理
    /// </summary>
    public void FixedUpdate()
    {
        RaycastHit hit;
        if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit))
        {
            this.cursor.transform.position = hit.point;
            this.cursor.transform.rotation = Quaternion.Euler(hit.normal);
            this.cursor.SetActive(true);

            var target = hit.collider.gameObject.GetComponent<Button>();
            if (target != null)
            {
                this.OnButtonOver();
            }
        }
        else
        {
            this.cursor.SetActive(false);
            this.OnButtonOut();
        }
    }

    /// <summary>
    /// 視線オーバーイベントハンドラ
    /// </summary>
    private void OnButtonOver()
    {
        this.buttonLabel.text = "Over";
    }

    /// <summary>
    /// 視線アウトイベントハンドラ
    /// </summary>
    private void OnButtonOut()
    {
        this.buttonLabel.text = "Button";
    }

    /// <summary>
    /// 視線クリックイベントハンドラ
    /// </summary>
    private void OnButtonClick()
    {
        this.buttonLabel.text = "Clicked";
    }
}

カーソルの GameObject を渡すフィールドを追加して、さらに視線が何かに衝突した場合ヒット情報の point プロパティをカーソルの座標に、normal(最大が 1 に正規化された向き情報)プロパティをもとにカーソルの角度を更新するようにしています

また Unity Ediotr に戻って Cursor オブジェクトを初期非アクティブにしたあと、先ほど追加した VRUI の Curosr プロパティに向けてドラッグドロップ

f:id:matatabi_ux:20160621190255p:plain

これで HoloLens エミュレーターで試してみました

f:id:matatabi_ux:20160621190327g:plain

視線位置にカーソルが表示されてわかりやすくなった!・・・のはいいんですが、どうも反応範囲が期待よりも倍くらい広くなっているような?

試しに Button に指定した BoxCollider を半分の大きさにしてみました

f:id:matatabi_ux:20160621190521p:plain

これでもう一度 HoloLens エミュレーターでお試し

f:id:matatabi_ux:20160621190548g:plain

今度はほぼぴったり!

うーん HoloLens 特有の調整が必要なのか、単にどこかの設定が誤っているのかちょっとよくわかりません;