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

Dec 2, 2018 - 1 minute read - HoloLens

HoloLensとUnity Editorで簡単にXboxコントローラーを動作させる

HoloLensで利用できるXBoxコントローラーを単一スクリプトで簡単に動作させてみます.(Editor動作も対応)

HoloLens側のコントローラー対応

HoloLensで接続できる無線機器(Bluetooth機器)にはハードウェアの規格上制限があります. 主に接続できる機器は以下になります.

  • HoloLensに付属しているクリッカー
  • Bluetoothマウス
  • Bluetoothキーボード
  • WindowsMR用モーションコントローラー(ボタン入力のみ)
  • Bluetooth搭載Xboxコントローラー

また上記のほかにもBluetooth HIDまたはGATTの一部プロファイルにも対応しています. (Bluetooth4.1搭載なのでペリフェラルモードのアドバタイズデータの受信も行えます.)

現状HoloLens対応のゲームコントローラーはUWPのAPIが対応しているBluetooth搭載Xboxコントローラーのみになっています.

HoloLensに対応しているBluetooth機器の情報

Unity側のコントローラー対応

Unity側にはゲームパッド入力値取得確認用APIが十分にそろえられており,入力ボタンのマッピングを行うことで異なる入力方式であっても柔軟に対応できるようになっています.

Unityのゲームコントローラーの設定情報

しかし入力デバイスによってはUnity側が提供しているAPIだけでは取得できない入力値があります.

Bluetooth搭載Xboxコントローラーでは以下の入力が取得できないようです.

  • DPad (十字ボタン)
  • RightThumbstick (右側アナログスティック)
  • Trigger (左右サイドボタンの下にあるアナログトリガー)

Unity側で対応していない入力はUWP側のAPIで取得することができます.

 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435
using Windows.Gaming.Input;

private Gamepad gamepad = null;

void Start()
{
  gamepad = (Gamepad.Gamepads.Count > 0) ? Gamepad.Gamepads[0] : null;
  Gamepad.GamepadAdded += (sender, e) => { gamepad = e; };
}

void Update()
{
    if (gamepad != null)
    {
        var reader = gamepad.GetCurrentReading();// コントローラーの入力セットを取得

        // 左アナログスティックの入力値を取得
        var lx = (float)reader.LeftThumbstickX;
        var ly = (float)reader.LeftThumbstickY;
        if (Mathf.Abs(lx) > 0.1f || Mathf.Abs(ly) > 0.1f) GetAxis.Invoke(XBoxStick.LeftThumbstick, new Vector2(lx, ly));

        // 右アナログスティックの入力値を取得
        var rx = (float)reader.RightThumbstickX;
        var ry = (float)reader.RightThumbstickY;
        if (Mathf.Abs(rx) > 0.1f || Mathf.Abs(ry) > 0.1f) GetAxis.Invoke(XBoxStick.RightThumbstick, new Vector2(rx, ry));

        // 左右トリガーの入力値を取得
        var lt = (float)reader.LeftTrigger;
        var rt = (float)reader.RightTrigger;
        if (Mathf.Abs(lt) > 0.1f || Mathf.Abs(rt) > 0.1f) GetAxis.Invoke(XBoxStick.Trigger, new Vector2(lt, rt));

        // ボタンの入力値を取得
        GetButton.Invoke((XBoxInput)reader.Buttons);// ボタンの取得
    }
}

UWP側のコントローラーは Gamepad クラスで取得します. アプリ起動後でも接続すればコントローラー接続イベントが発行されるので GamepadAdded で再取得できます.

これでHoloLens(UWP)側のXboxコントローラー入力値を全て取得することができます.


以下にEditor動作(Unity)とHoloLens動作(UWP)を切り分けて同様の入力値を取得できるようにしたスクリプトを作成しました. 取得した入力値はUnityEventで外部から取得することができます.

https://github.com/akihiro0105/HoloLensModule/blob/master/Assets/HoloLensModule/Input/Scripts/XBoxController.cs

振動機能

XboxコントローラーはUWP側のAPIから振動機能を利用することもできます. コントローラーには左右に振動子がありそれぞれ独立して動作させることができます.

1234
 GamepadVibration gamepadVibration = new GamepadVibration();
                gamepadVibration.LeftMotor = rPower;// コントローラー左側の振動子の振動の強度を指定
                gamepadVibration.RightMotor = lPower;// コントローラー右側の振動子の振動の強度を指定
                gamepad.Vibration = gamepadVibration;// 振動開始

振動は0.0f~1.0fで変化させることができ,設定後は振動の強度を変更するまで振動し続けます. そのため振動させた後は左右の振動子の動作を0.0fにして停止させる必要があります.

ゲームパッドの振動に関する情報

まとめ

  • MixedRealityToolkitのバージョンによってはXboxコントローラーの入力値が正常に取得できない場合もあるみたい.
  • とりあえずすぐに動作させて動作確認したい場合にはスクリプト1個で簡単に済ませたい.
  • コントローラーの状態によっては振動しない場合がある(バージョン,充電状態によるかも)

https://github.com/akihiro0105/HoloLensModule/blob/master/Assets/HoloLensModule/Input/Scripts/XBoxController.cs