HoloTips:何もないところをAirTapしたときにアクションを起こす

投稿者: | 2017-05-11

過去の記事でも書いた通り、HoloLensアプリでジェスチャー入力を利用したいときは、HoloToolkit-UnityのInputManagerを使うと簡単に実装することができます。例えばAirTapで何かしらの操作をしたいときはIInputClickHandlerインタフェースを実装したスクリプトを用意し、それをコライダーをもつオブジェクトにアタッチしてあげるだけで、AirTap操作を実装することができます。

このような何かしらのオブジェクトに対してジェスチャーイベントを作用させる方法はわかりました。では何もない空間に対してジェスチャーイベントを作用させるにはどうすればいいのでしょうか。

解決策

実はこれもInputManagerを使えば解決できます。

InputManagerにはAddGlobalListnerというメソッドが用意されています。このメソッドは全てのジェスチャーイベントをキャッチするGameObjectを指定するためのメソッドです。したがって、このメソッドにジェスチャーイベントをハンドリングするインタフェースを実装したGameObjectを渡してやると、以降はいかなる場所でそのジェスチャーを行ったときに反応するようになります。

実際にサンプルを作ってみます。いつも通り、HoloLensCamera、InputManger、DefaultCursorをシーンに配置し、空っぽのGameObjectにスクリプトをアタッチします。

アタッチしたスクリプトの内容は以下の通りです。

using HoloToolkit.Unity.InputModule;
using UnityEngine;

public class NothingSpaceClickHandler : MonoBehaviour, IInputClickHandler {
    void Start () {
        // 全てのジェスチャーイベントをキャッチできるようにする
        InputManager.Instance.AddGlobalListener(gameObject);
	}
	
    /// AirTapイベントのハンドラ
    public void OnInputClicked(InputClickedEventData eventData) {
        // ログを吐くだけ
        Debug.Log("Click on nothing point !!!!");
    }
}

これで何もない空間をAirTapしたときに何らかのアクションを起こすことが可能となりました。

と言いたいのですが、実はこれだけだと少し問題があります。というのもAddGlobalListnerでイベントリスナーを設定した場合は、本当にいついかなるときもジェスチャーに反応してしまいます。例えば、AirTapに反応するCubeがシーンに配置されていた場合、このCubeをAirTapしたときにはCubeだけでなくAddGlobalListnerで指定したGameObjectも反応してしまいます。これではちょっと融通が利いていないですね。

それを防ぐためには先ほどのコードを少し修正します。

using HoloToolkit.Unity.InputModule;
using UnityEngine;

public class NothingSpaceClickHandler : MonoBehaviour, IInputClickHandler {
    void Start () {
        // 全てのジェスチャーイベントをキャッチできるようにする
        InputManager.Instance.AddGlobalListener(gameObject);
	}
	
    /// AirTapイベントのハンドラ
    public void OnInputClicked(InputClickedEventData eventData) {
        // 何もGazeしていないときだけ動作する
        if (!GazeManager.Instance.HitObject) {
            // ログを吐くだけ
            Debug.Log("Click on nothing point !!!!");
        }
    }
}

これで3Dモデルに対してジェスチャーしたときと、何もない空間に対してジェスチャーをしたときの動作を分離することができるようになります。

まとめ

ジェスチャー入力についてのTipsを記載しました。

InputManagerは色々な機能を持っている割には、GitHubのREADMEにそれほど情報が書かれていないので、一度中身をじっくり読んでリファレンスにしてまとめておきたいなあ、と思っています。(破壊的変更で一気にオジャンになる可能性もありますが…)