なんかいろいろしてみます

Nov 15, 2017 - 1 minute read - HoloLens

HoloLensで利用できるジェスチャー入力について(Unity 2017.1まで編)

HoloLensで行うジェスチャー入力(AirTap,Drag)をUnityで利用する場合の機能と使い方について書いています.

HoloLensのジェスチャー入力とは

HoloLensでは外部のデバイスを用いることなく操作が行えるようになっています. 基本はマウス操作でのクリックに対応する「AirTap」,ドラッグ動作に相当する「Drag」,Windowsキーに対応する「Bloom」があります. HoloLensにBluetoothマウス,キーボード,ゲームコントローラーと接続することもできますが,ジェスチャー操作を行うことでハンズフリーでの操作が実現されています. 他の入力方法としては音声認識によるボイスコントロールがありますが,現在は英語のみの対応となっています.

今回はUnity 2017.1までのバージョンに対応した内容になっています. Unity 2017.2以降の変更点などに関しては別途記事を用意しています.

Unityでジェスチャー入力を利用してみる

UnityではHoloLensからのハンドジェスチャー操作に対応するために専用の関数が用意されています. Unityが提供している関数のためUnityEditor上では動作しHoloLens用の切り分けは必要ありません(もちろんEditor上ではジェスチャー操作できませんが).

Unity 2017.1までは

 using UnityEngine.VR.WSA.Input; 
を利用します.

ジェスチャー入力はイベント通知によって取得することができます. InteractionManagerにイベントを登録することで以下のようにそれぞれの状態が取得できます.

 1void Start()
 2{
 3    InteractionManager.SourceDetected += SourceDetected;
 4    InteractionManager.SourceUpdated += SourceUpdated;
 5    InteractionManager.SourceLost += SourceLost;
 6    InteractionManager.SourcePressed += SourcePressed;
 7    InteractionManager.SourceReleased += SourceReleased;
 8}
 9
10void SourceDetected(InteractionSourceState state)
11{
12  // Detect
13}
14
15void SourceUpdated(InteractionSourceState state)
16{
17  // Update
18}
19
20void SourceLost(InteractionSourceState state)
21{
22  // Lost
23}
24
25void SourcePressed(InteractionSourceState state)
26{
27  // Press
28}
29
30void SourceReleased(InteractionSourceState state)
31{
32  // Release
33}

SourceDetectedではHoloLensが手を認識した時に呼び出されます. HoloLensではAirTap前の手のポーズの時点で手の認識を行いハンドトラッキングを開始します. 逆にAirTap前の状態でないと正しく手の認識を行ってくれません.(手を握ったままだとダメ)

SourceUpdatedはHoloLensが手を認識した時から見失うまで毎回呼び出されます. これは後述のPress状態でも同様です.

SourceLostではHoloLensが手を見失いハンドトラッキングができなくなった状態に呼び出されます. HoloLensのハンドトラッキングの範囲は上方向は狭く下方向には広い作りになっています. HoloLensの表示領域外から外れてもある程度ならトラッキングを続けることができます.

SourcePressedではハンドトラッキングされた手がAirTap状態(指を倒した状態)になったときに呼び出されます. AirTap状態でもハンドトラッキングは継続して行われているためDrag動作が可能になっています.

SourceReleasedはAirTap状態から手をAirTap前に戻したときに呼び出されます.

それぞれの状態時に呼び足されたイベントによってHoloLensのジェスチャー操作を行うことができます. 各イベントの引数InteractionSourceStateにはハンドトラッキングの状態を取得することができます. 例えばSourceUpdatedの場合以下のような情報が取得できます.

1void SourceUpdated(InteractionSourceState state)
2{
3    Vector3 v;
4    if (state.properties.location.TryGetPosition(out v) == true)
5    {
6        Debug.Log(state.source.id + " " + state.pressed);
7    }
8}

4行目では引数のstateからトラッキングを行っている手の絶対座標が取得できます. 6行目の変数は手が認識された時の固有番号(id)とAirTap状態か(pressed)がわかるようになっています. 固有番号はアプリ起動時から認識された順番に割り当てられ認識されたいる手の数だけ各イベントが呼び出されます.

簡単にAirTapのみの確認を行いたいだけであれば以下のようにすることでできます.

1void Start()
2{
3    InteractionManager.SourcePressed += (state)=>{
4      // AirTapで動作させたい処理
5    };
6}

HoloLensでオリジナルなジェスチャー操作を利用してみる

Unityでは上記のように4つのイベントからの通知を受け取ることで様々なジェスチャーを認識させることができます. 各イベントはトラッキングしている手の数だけ呼び出され,それぞれに固有番号が付けられています. そのため片手で行う従来のAirTap動作の他にも両手を使った動作,AirTap以外のジェスチャーを独自に実装することができます.

このInput機能を用いたHoloLensModuleでは複数の独自ジェスチャーを試すことができます(自分で作った). 操作は以下のようなことが可能です.

  • Tap

  • DoubleTap

  • Hold

  • Drag

  • ShiftTap

  • ShiftDoubleTap

  • ShiftHold

  • ShiftDrag

  • MultiTap

  • MultiDoubleTap

  • MultiDrag

各ハンドトラッキング情報を固有番号で管理してAirTapの有無と時間からそれぞれのジェスチャーを実装しています. さらに各ハンドトラッキングの位置も取得できるので左右の手を識別して独自ジェスチャーを追加することもできます(今後したい).

まとめ

  • 簡単にジェスチャー入力を実現したい場合は公式が提供しているMixedRealityToolkitを使った方がいい.
  • MixedRealityToolkitを使うと便利.
  • 複雑なジェスチャー操作は初心者には難しいので基本はAirTapのみがいいと思う.
  • 未来感出すなら両手で操作する感じでもかっこいいかも
  • HoloLensの機能を集めたHoloLensModule作ってます.