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

Nov 18, 2017 - 1 minute read - HoloLens

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

前の記事でHoloLensでのInputの利用方法を紹介しましたがUnity2017.2からAPIの変更がありました. 変更部分の紹介について書いています.

Unity2017.1までは前の記事に書いてます.

Unity2017.2からHoloLensのInputが変更になりました

Unityのバージョンが2017.2になってからImmersiveデバイスの対応が行われ一部APIの変更が行われました. この変更でHoloLensの開発では一部namespaceの変更と関数の変更が必要になっています.

Unity2017.2で変更になった部分

namespaceの変更

HoloLensの機能(InputやWorldAnchor)を利用する場合Unity2017.1まではnamespaceを

using UnityEngine.VR.WSA;
と設定していましたが,Unity2017.2からは
using UnityEngine.XR.WSA;
とする必要があります.

これによりWorldAnchorをUnity2017.1とUnity2017.2の両方で使用する場合は以下のように記述する必要があります.

1234567
#if !UNITY_2017_2_OR_NEWER
using UnityEngine.VR.WSA;
using UnityEngine.VR.WSA.Persistence;
#else
using UnityEngine.XR.WSA;
using UnityEngine.XR.WSA.Persistence;
#endif

ただしWorldAnchorの利用関数名は変更になっていないのでusing以外の変更は必要ないです.

InputのAPI変更

HoloLensでInputを利用する場合もWorldAnchor同様にusingを以下ののように変更します.

12345
#if !UNITY_2017_2_OR_NEWER
using UnityEngine.VR.WSA.Input;
#else
using UnityEngine.XR.WSA.Input;
#endif

しかしながらInputではInteractionManager以下の関数名も変更になっています.

 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233
void Start()
{
    InteractionManager.InteractionSourceDetected += SourceDetected;
    InteractionManager.InteractionSourceUpdated += SourceUpdated;
    InteractionManager.InteractionSourceLost += SourceLost;
    InteractionManager.InteractionSourcePressed += SourcePressed;
    InteractionManager.InteractionSourceReleased += SourceReleased;
}

void SourceDetected(InteractionSourceDetectedEventArgs state)
{
  // Detect
}

void SourceUpdated(InteractionSourceUpdatedEventArgs state)
{
  // Update
}

void SourceLost(InteractionSourceLostEventArgs state)
{
  // Lost
}

void SourcePressed(InteractionSourcePressedEventArgs state)
{
  // Press
}

void SourceReleased(InteractionSourceReleasedEventArgs state)
{
  // Release
}

変更点としては

  • SourceDetected -> InteractionSourceDetected
  • SourceUpdated -> InteractionSourceUpdated
  • SourceLost -> InteractionSourceLost
  • SourcePressed -> InteractionSourcePressed
  • SourceReleased -> InteractionSourceReleased

に変更になっています.

またそれぞれのイベントの引数が

  • InteractionSourceDetectedEventArgs
  • InteractionSourceUpdatedEventArgs
  • InteractionSourceLostEventArgs
  • InteractionSourcePressedEventArgs
  • InteractionSourceReleasedEventArgs

に代わっています.(全部バラバラになってる) 引数名がばらばらになっていますが内部の変数にInteractionSourceStateがあります. 例えばハンドトラッキングされた手の位置を取得した場合には以下のようにすると取得できます.

12345678
void SourceUpdated(InteractionSourceUpdatedEventArgs state)
{
    Vector3 v;
    if (state.state.sourcePose.TryGetPosition(out v) == true)
    {
      Debug.Log(state.state.source.id + " " + state.state.pressed);
    }
}

Immersiveデバイスへの対応

Unity2017.2からImmersiveデバイスへの対応が正式に行われたためHoloLensと同じUWPで動作するようになりました. そのためImmersiveデバイスのモーションコントローラーとHoloLensは同じ関数を利用することでInputを取得できます. 同じコードを利用してインストール先を変えるだけで以下のようにHoloLensとImersiveデバイスの両方に対応することができます.

  • HoloLensにインストールした場合

    (白い球がハンドトラッキングしている手の位置です)

  • Immersiveデバイスにインストールした場合

    (白い球がハンドトラッキングしているモーションコントローラーの位置です)

気を付けるポイント

  • 動作は一緒じゃない

    • HoloLensとImmersiveのモーションコントローラーの動作は同じではないです
  • HoloLensの場合

    • 手をHoloLensの認識範囲内に入れるとDetectで認識開始
    • 手をHoloLensの認識範囲外に移動するとLostで認識終了
  • Immersiveの場合

    • 起動時に接続されているモーションコントローラーをDetectで認識開始
    • モーションコントローラーをImmersiveヘッドマウントディスプレイの認識範囲外に移動してもLostで認識終了しない
    • 途中でモーションコントローラーの接続を切ってもLostで認識終了しない
    • 途中でモーションコントローラーを接続してもDetectで認識開始しない

まとめ

  • 関数が一部変わってUnityのバージョン間の切り分けが発生した.
  • APIが変わってUnityのバージョン間の切り分けが発生した.
  • HoloLensとImmersiveで挙動が異なる場合があるので切り分けが発生した.
  • Unityのバージョンは固定した方がいいと思います.