HoloLensが届きました!
こんな感じでVRで作っていた「Makebox」の移植をしてみました。Unityで開発できて、開発環境も揃っているので楽しいですよ!
今回は「HoloToolKit-Unityを使用した入力の取得方法」をまとめてみました。
これができるようになれば、後はUnityのコードをがりがり書くだけで色々な表現ができるようになるはずです。
HoloToolKitの導入はこちらを参照してください。
HoloToolkit-Unity/GettingStarted.md at master · Microsoft/HoloToolkit-Unity · GitHub
以下のオブジェクトがシーンに存在する状態で使用してください
HoloLensCamera.prefab
InputManager.prefab
DefaultCursor.prefab
EventSystem
紹介する機能
機能 | モジュール名 | コールバックのタイミング |
---|---|---|
入力 | IInputHandler | 対象へのInputDown / 対象へのInputUp |
クリック | IInputClickHandler | 対象へのクリック |
フォーカス | IFocusable | 対象とGazeが重なったとき / 対象からGazeが外れたとき |
手の検出 | ISourceStateHandler | 対象を見ている状態で手が認識されているとき / 対象を見ている状態で手が認識から外れたとき |
ホールド | IHoldHandler | 対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した |
ドラッグ(操作) | IManipulationHandler | 対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した / 途中でトラッキングが外れた |
ドラッグ(ナビゲーション) | INavigationHandler | 対象をつまみだした / 対象をつまんでいる / 対象をつまみ外した / 途中でトラッキングが外れた |
音声の検出 | ISpeechHandler | 対象を見ながらしゃべった時のテキストを返す |
※ IManipulationHandler、INavigationHandlerの違いについて
Manipulationは空間でものを動かしたり、何か書いたりしている基本的な動かすことに向いている。
Navigationはジョイスティックのようなもので、閾値(-1~1)も設定されているので、UIとかで使ったりするのに向いている。
詳細は下記
https://developer.microsoft.com/en-us/windows/holographic/Gestures.html#manipulation
※「対象」というのはスクリプトとコライダーがアタッチされているゲームオブジェクトを指します。
またSetGlobalListenerを同じオブジェクトにアタッチすることで、どこを見ていてもコライダーをつけずにイベントを発火することが可能です。
概要
それぞれのモジュールを継承することで、任意のコールバックが呼ばれるような仕組みとなっています。
Monobehaviourを継承したら、StartやUpdateが呼ばれるような感じで、Inputの際も定義したコールバックが呼ばれます。
使い方
InputModuleをusing
using HoloToolkit.Unity.InputModule;
使用するモジュールを継承(複数可)
public class InputTest : MonoBehaviour, IInputHandler, IInputClickHandler, IFocusable
コールバックを定義する
IInputHandler
public void OnInputUp(InputEventData eventData) { Debug.LogFormat("OnInputUp\r\nSource: {0} SourceId: {1}", eventData.InputSource, eventData.SourceId); } public void OnInputDown(InputEventData eventData) { Debug.LogFormat("OnInputDown\r\nSource: {0} SourceId: {1}", eventData.InputSource, eventData.SourceId); }
IInputClickHandler
public void OnInputClicked(InputClickedEventData eventData) { Debug.LogFormat("OnInputClicked\r\nSource: {0} SourceId: {1} TapCount: {2}", eventData.InputSource, eventData.SourceId, eventData.TapCount); }
IFocusable
public void OnFocusEnter() { Debug.Log("OnFocusEnter"); } public void OnFocusExit() { Debug.Log("OnFocusExit"); }
ISourceStateHandler
public void OnSourceDetected(SourceStateEventData eventData) { Debug.LogFormat("OnSourceDetected\r\nSource: {0} SourceId: {1}", eventData.InputSource, eventData.SourceId); } public void OnSourceLost(SourceStateEventData eventData) { Debug.LogFormat("OnSourceLost\r\nSource: {0} SourceId: {1}", eventData.InputSource, eventData.SourceId); }
手の検知はあんまり知られてなさそう。仕組み的に指さし->パーの検知ができる。ちょっと何かに使えるかも?
IHoldHandler
public void OnHoldStarted(HoldEventData eventData) { Debug.LogFormat("OnHoldStarted\r\nSource: {0} SourceId: {1}", eventData.InputSource, eventData.SourceId); } public void OnHoldCompleted(HoldEventData eventData) { Debug.LogFormat("OnHoldCompleted\r\nSource: {0} SourceId: {1}", eventData.InputSource, eventData.SourceId); } public void OnHoldCanceled(HoldEventData eventData) { Debug.LogFormat("OnHoldCanceled\r\nSource: {0} SourceId: {1}", eventData.InputSource, eventData.SourceId); }
IManipulationHandler
public void OnManipulationStarted(ManipulationEventData eventData) { Debug.LogFormat("OnManipulationStarted\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); } public void OnManipulationUpdated(ManipulationEventData eventData) { Debug.LogFormat("OnManipulationUpdated\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); } public void OnManipulationCompleted(ManipulationEventData eventData) { Debug.LogFormat("OnManipulationCompleted\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); } public void OnManipulationCanceled(ManipulationEventData eventData) { Debug.LogFormat("OnManipulationCanceled\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); }
INavigationHandler
public void OnNavigationStarted(NavigationEventData eventData) { Debug.LogFormat("OnNavigationStarted\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); } public void OnNavigationUpdated(NavigationEventData eventData) { Debug.LogFormat("OnNavigationUpdated\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); } public void OnNavigationCompleted(NavigationEventData eventData) { Debug.LogFormat("OnNavigationCompleted\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); } public void OnNavigationCanceled(NavigationEventData eventData) { Debug.LogFormat("OnNavigationCanceled\r\nSource: {0} SourceId: {1}\r\nCumulativeDelta: {2} {3} {4}", eventData.InputSource, eventData.SourceId, eventData.CumulativeDelta.x, eventData.CumulativeDelta.y, eventData.CumulativeDelta.z); }
ISpeechHandler
使用される単語をどれか一つのオブジェクトにあらかじめ登録しておく必要があります。
SpeechInputSourceを任意のオブジェクトにアタッチし、単語を登録する。
public void OnSpeechKeywordRecognized(SpeechKeywordRecognizedEventData eventData) { Debug.Log(eventData.RecognizedText.ToLower()); }
最後に
これでインタラクションコンテンツが作れるようになるのではないでしょうか。
また、間違った記載がありましたら、コメントやTwitter等でご指摘ください。