HoloLensでジェスチャー処理をするときによく使うのはGestureRecognizerです。これを使えばair-tapやドラッグのジェスチャーを簡単に処理することができます。
しかしこれだけではジェスチャーをしていない時に手がどこにあるかをトラッキングできません。ジェスチャーをしていないときに常に手の位置を把握しようと思ったら、InteractionManagerを使うと良いです。このクラスはインスタンス化することなくstatic
に使用します。
InteractionManager.InteractionSourceUpdated
に登録するとHoloLensが手を検出している間、手の位置が変更されたりする度に通知が呼び出されます。このイベントハンドラ内で手の位置を取得すれば、ジェスチャーをしているかどうかに関係なく常に手の位置をトラッキングできます。
InteractionManager.InteractionSourcePressed
,InteractionManager.InteractionSourceReleased
で指の上げ下げのタイミングが拾えます。InteractionManager.InteractionSourceLost
で手が視界から消えたタイミングが拾えます。
簡単な例として、手の位置に球のオブジェクトを表示するサンプルを下記に載せます(シーン内にSphereという名前の球オブジェクトが存在する前提)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.WSA.Input;
public class HandPosition : MonoBehaviour
{
public GameObject target;
void Start()
{
InteractionManager.InteractionSourceUpdated += InteractionSourceUpdated;
InteractionManager.InteractionSourcePressed += InteractionSourcePressed;
InteractionManager.InteractionSourceReleased += InteractionSourceReleased;
InteractionManager.InteractionSourceLost += InteractionSourceLost;
}
// HoloLensが手を検出している間、位置が変わったりするたびに呼ばれる。
private void InteractionSourceUpdated(InteractionSourceUpdatedEventArgs ev)
{
// 手の位置に置くオブジェクトがnullでなければ
if (target != null)
{
// 手の位置を取得して
Vector3 position;
if (ev.state.sourcePose.TryGetPosition(out position))
{
// オブジェクトの位置を手の位置に更新
target.transform.position = position;
}
}
}
// air-tap の指を下ろした時に呼ばれる
private void InteractionSourcePressed(InteractionSourcePressedEventArgs ev)
{
// シーンの中にある Sphere というオブジェクトを手の位置に持ってくるようにする
target = GameObject.Find("Sphere");
}
// air-tap の指を上げた時に呼ばれる
private void InteractionSourceReleased(InteractionSourceReleasedEventArgs ev)
{
target = null;
}
// 手が視界から外れた時に呼ばれる
private void InteractionSourceLost(InteractionSourceLostEventArgs ev)
{
target = null;
}
}