HoloLensで始めるMixed Reality Toolkit - Unity ～HoloLensで有効なイベントの種類について


# Mixed Reality Tookit - Unityのイベントについて
[先日](https://qiita.com/miyaura/items/6419d554daeb4f366511)、Mixed Reality Tookit - Unity(以下MRTK)のイベントの内モーションコントローラ向けに使えるものを整理しました。HoloLensだとどこまで使えるのかも調査してみました。

## 環境
今回の環境は以下の通りです。

* Windows 10 Pro Fall Creators Update
* Unity 2017.2.1f1
* Mixed Reality Toolkit - Unity 2017.2.0.1

上記の環境はWinMRの環境でもあるのですが、HoloLensでも開発できるようになりました（やったー）。

## HoloLensで使えるイベント

MRTKのイベントについては一通り[先日](https://qiita.com/miyaura/items/6419d554daeb4f366511)説明していますので、HoloLensで有効だったイベントをリストにするとともに挙動で補足が必要な物を説明します。

|インターフェース|説明|使用可否|
|:-:|:--|:-:|
|IControllerInputHandler|タッチパッドや親指スティックの操作時のイベントを利用できます。|-|
|IControllerTouchpadHandler|タッチパッドのボタンとしての操作時のイベントを利用できます。|-|
|IDictationHandler|音声入力時のイベントを利用できます。|〇|
|IFocusable|フォーカスの制御に反応するイベントに利用できます。|〇|
|IGamePadHandler|ゲームパッドの検出に反応するイベントを利用できます。|-|
|IHoldHandler|ボタン押下状態に関するイベントを利用できます。|〇|
|IInputClickHandler|クリック操作（AirTapやボタンクリック）に対するイベントを利用できます。|〇|
|IInputHandler|ボタンの押下に対するイベントを利用できます。|〇|
|IManipulationHandler|ボタン押下中等の操作に対するイベントを利用できます。|〇|
|INavigationHandler|ナビゲーションジェスチャーに反応するイベントを利用できます。|〇|
|IPointerSpecificFocusable|ポインターごとのフォーカスの入力/終了に反応するイベントを利用できます。|〇|
|ISelectHandler|モーションコントローラのSelectボタンの押下に反応するイベントを利用できます。|-|
|ISourcePositionHandler|入力ソース（モーションコントローラ等）の位置移動に反応するイベントを利用できます。|〇|
|ISourceRotationHandler|入力ソース（モーションコントローラ等）の回転に反応するイベントを利用できます。|-|
|ISourceStateHandler|入力ソースの変更に反応するイベントを利用できます。|〇|
|ISpeechHandler|音声入力のキーワード検出に反応するイベントを利用できます。|〇|
|IXboxControllerHandler|Xboxのスティック操作に反応するイベントを利用できます。|-|

#### IDictationHandlerインターフェース
Unityでも機能としてある音声認識の機能と同じ考え方のイベントです。実際には、UnityのDictationRecognizerのイベントを置換えてるインターフェースです。このインターフェースを利用する場合はMRTKのDictationInputManagerを追加し、音声認識を実施するように実装します。各イベントの発生はDictationRecognizerと同じです。

#### IFocusableインターフェース
Gazeのポインタが対象物に当たる/外れる場合に発生するイベントに対応する以下のメソッドを実装します。このインターフェースは対象物のオブジェクトに対して設定します。モーションコントローラのポインタがこのオブジェクトに当たるとイベントが発生します。(後述のIPointerSpecificFocusableとタイミングは同じ)

#### IHoldHandlerインターフェース
AirTapによるHold状態を利用する場合に以下のメソッドを実装します。考え方として、AirTapでしばらくするとHoldStarted、そのままReleaseするとHoldCompletedとなります。HoldCanceledはボタン押下したまま、<font color="red">手を動かすと発生します。</font>この時、Manipulation系、Navigation系が発生します。

#### IInputClickHandlerインターフェース
おなじみクリック時に発生する以下のメソッドを実装します。AirTapで発生します。

#### IInputHandlerインターフェース
AirTapで「押す」と「離す」ときに発生する以下のメソッドを実装します。クリックの前後で発生するイベントです。

#### IManipulationHandlerインターフェース
Hold状態から手を動かす際に発生する以下のメソッドを実装します。INavigationHandlerインターフェースとイベントの発生タイミングは同じです。このイベントではAirTapを行った位置を原点にコントローラの変化量を取得することができます。

#### INavigationHandlerインターフェース
Hold状態から手を動かす際に発生する以下のメソッドを実装します。IManipulationHandlerインターフェースをイベントの発生タイミングは同じで、AirTapした位置を原点にコントローラを変化量を-1~1の範囲で正規化して取得することができます。

##### IPointerSpecificFocusableインターフェース
Gazeのポインタが対象物に当たる/外れる場合に発生するイベントに対応する以下のメソッドを実装します。このインターフェースは対象物のオブジェクトに対して設定します。モーションコントローラのポインタがこのオブジェクトに当たるとイベントが発生します。

#### ISourcePositionHandlerインターフェース
入力ソースの移動が発生した場合のイベントを以下のメソッドで実装します。手がセンサー内にある時で人差し指を立てている状態で発生します。HoloLensで移動中全体でとる場合は、このインターフェースとIManipulationHandlerインターフェースを組み合わせるといいと思います。

#### ISourceStateHandlerインターフェース
入力ソースの状態が変化した場合のイベントを以下のメソッドで実装します。手がセンサー内で補足されたときにDetect、検出外になった場合Lostとなります。

#### ISpeechHandlerインターフェース
これもUnityにもある音声認識を拡張したものですね。こちらはKeywordRecognizerのイベントを置換える形で利用するインターフェースです。利用する場合はコンポーネントとしてSpeechInputSourceを追加しそのプロパティでキーワードを設定することでこのインターフェースのメソッドを呼び出される仕様になっています。使用するキーワードに応じてSpeechInputSourceを複数登録しておき、まとめてISpeechHandlerインターフェースで処理するような形になっています。

## 最後に
MRTK使うなら比較的ライトに使えるイベントそろっているので仕様にあうものがあれば使っていくとよいと思います。