littlewing

人間とコンピューターとメディアの接点をデザインするために考えたこと

HoloLensでXbox One用のゲームパッドを使う

f:id:pigshape:20170607110155j:plain

UnityでのHoloLensアプリ開発にXboxOne用のゲームパッド(コントローラー)を利用してみました。利用までの手順などをまとめます。

ちなみにある程度動作したのですが、一部うまく動いていない状況です。 調査と試行錯誤の記録としてメモしておきます。

追記2018/6/17 この記事の課題の解決方法を、別記事に簡単にまとめました。 * HoloLensでXbox One用のゲームパッドを使う2-その後 - littlewing

1.まず、コントローラーを手に入れる
BlueTooth対応必須

Xbox One用のコントローラーには複数種類ありまして

  • 有線専用のコントローラー(Amazonで\2,500円くらい)
  • BlueTooth非対応の無線コントローラー(同、3,500円程度)
  • BlueTooth対応の無線コントローラー(同、5,800円程度)

があり、この中でBlueTooth対応のXboxOne用コントローラーが必要なので注意。

Xbox One S同梱のコントローラー以降からBlueTooth対応になったようで比較的最近発売されたコントローラーが必要です。

  • Oculus CV1用のXboxコントローラーはBlueTooth非対応らしく使えないとの事。
  • またXbox 360用の無線コントローラーも使えません。(自宅に4つあるのに残念。。)

具体的には、Amazonでこれを買いました。

BlueTooth対応なのでWindows PCとも接続できます。単三電池2本で動くのですが、パッケージには入っていませんでした。 有線用のUSBケーブルは付属しています。

BlueTooth接続だと、文字入力できるオプションのChat用キーパッドは利用できないとの事。残念です。

また、余談ですが、Windows 10 のStoreからダウンロードできるUWPアプリはゲームパッド対応のものもあるのですが、一般的なWindowsゲームパッドではなぜか動作せず、Xbox One用のコントローラーでないと動かないものが多いようです。

上記コントローラーを購入すれば、それらのゲームも遊べるので、そういう意味でも買っておいて損は無いと思います。 Win10上でツインビーゲームパッドで遊べました。

f:id:pigshape:20170604213300p:plain

出たな!! ツインビー を購入 - Microsoft Store ja-JP

そして、コントローラー単体で6,000円近くするのですが、あと、2万円も追加すれば、コントローラー付きのXbox One Sが買えてしまいます。 Xbox One SはHoloLensと連携して、HoloLensを画面に出せるらしいので、こっち買っちゃったほうが良いかも。


2.HoloLensと接続する

HoloLensと接続するのは簡単です。 HoloLens内のSettings アプリから、BlueToothバイスとして追加します。 Storeアプリなど2Dのプレインストールアプリなども一部XboxOneコントローラーに対応済みです。 全ての操作が完結する訳ではないですが、いちいちエアタップしなく良いので結構便利。

HoloLensのXbox One用コントローラーサポートは2016年夏のAnniversary Updateにて対応されたようです。

Gamepad Support
You can now pair and use Bluetooth gamepads with HoloLens! The newly released Xbox Wireless Controller S features Bluetooth capabilities and can be used to play your favorite gamepad-enabled games and apps. A controller update must be applied before you can connect the Xbox Wireless Controller S with HoloLens.
The Xbox Wireless Controller S is supported by XInput and Windows.Gaming.Input APIs. Additional models of Bluetooth controllers may be accessed through the Windows.Gaming.Input API.

Windows.Gaming.Input API.とXInputの話はあとで出てきます。


3.開発用PCと接続する。

次に開発用PCにコントローラーを接続してみます。一般的なBlueToothバイスの追加手順です。

Pinコードなど不要で接続できました。


4.Unity上で使えるようにする。

次に開発PC上のUnityEditor上でコントローラーを利用可能にしていきます。

Unityは5.6.1fを利用。

前提知識

話がそれますが、PC用ゲームコントローラーの仕組みを理解するには

  • Direct Input
  • XInput
  • Windows.​Gaming.​Input

というキーワードを知っておく必要があります。

簡単に言うとXInputはMicroSoft製品と親和性が高く、キーの割り当て仕様が統一されています。 Xbox360用のコントローラーはXInput対応だそうです。

もう少し詳しくDirect InputとXInputの違いを知りたい方はこのサイトが参考になります。

ただし、以前はWindows専用のゲームアプリなどはXInputベースで開発すればよかったのですが、ややこしいことにUWPアプリにおいては Windows.​Gaming.​Input APIを利用して操作内容を取得することが推奨されています。

Windows.Gaming.Input API は XInput を置き換える API であり、同じ機能を提供すると共に、XInput に比べて次のような利点があります。
* リソースの使用量が少ない
* 入力を取得するための API 呼び出しの待ち時間が短い
* 同時に 4 つ以上のゲームパッドを処理する機能
* トリガー バイブレーション モーターなど、追加の Xbox One ゲームパッド機能にアクセスする機能
* コントローラー接続/切断をポーリングではなくイベントで通知する機能
* 入力を特定のユーザー (Windows.System.User) に関連付ける機能
使う状況
ゲームでゲームパッド入力をサポートする必要があるが、XInput の既存のコードを使っていない場合や、上に示したメリットのいずれかが必要である場合は、Windows.Gaming.Input を使う必要があります。

ただし、Unity 5.4の頃からUnityがWindows Store向けアプリにおける、HID devicesのサポートをするようになりました。そのため、#if WINDOWS_UWPなどで分岐して Windows.​Gaming.​Inputの記述をしなくても、大丈夫なようになったようです。

ただ、こちらの記事の方はWindows.Gaming.Input API.を利用した実装を紹介しています。

この辺り、正直よくわかりません。HoloLensのフォーラムもコントローラー周りは荒れ気味なので、なんか嫌な予感。。


ここで、ぴったりのAssetを見つけたが動作せず。。

ここまで調べていたら、AssetStore上に、XboxControllerをHoloLensで使うためのピッタリのパッケージを見つけたので 最初に試してみます。

ただ。私の環境でビルドはできたのですが、実機転送したら以下のエラーが出まくって、正常に動作しませんでした。

Exception thrown: 'System.Exception' in System.Private.CoreLib.ni.dll
Exception thrown: 'System.ArgumentOutOfRangeException' in System.Private.CoreLib.ni.dll
ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: index
   at System.Runtime.InteropServices.WindowsRuntime.IVectorViewToIReadOnlyListAdapter.Indexer_Get[T](Int32 index)
   at HoloLensXboxController.ControllerInput.Update()
   at ControllerInputExample.Update()
   at ControllerInputExample.$Invoke12Update(Int64 instance, Int64* args)
   at UnityEngine.Internal.$MethodUtility.InvokeMethod(Int64 instance, Int64* args, IntPtr method) 
(Filename: <Unknown> Line: 0)

Aseetの中身もdllの状態でソースコードが入っておらず解析もできず。。

また導入できたとしてもUnityEditor上では動作しないと書いてあるので、いったんあきらめて正攻法を試してみます。


InputManagerでキーの割り当てを行う。

ゲームコントローラーなどを追加する際は、通常はEditor上の、 Edit -> Project Settings -> Input(Manager)で、キーの紐づけなどを行うことになります。

表面 裏面
f:id:pigshape:20170607154103p:plain f:id:pigshape:20170607154120p:plain

以下のように設定したら、UnityEditor + Xbox One Controllerでは正常に動作しました。

2017/7/8追記 MRDesignLabを使っている場合は、Inputの設定は行われているので、Nameの部分はそれを使った方が良いです。そのうち書き換えるかも。


Name
(InputManagerで設定)
Positive Button 部品名称 図ID
Fire1 joystick button 0 A Button A
Fire2 joystick button 1 B Button B
Fire3 joystick button 2 X Button X
Jump joystick button 3 Y Button Y
XB1LeftShoulder joystick button 4 XB1LeftShoulder 2
XB1RightShoulder joystick button 5 XB1RightShoulder 7
XB1View joystick button 6 XB1View 3
XB1Menu joystick button 7 XB1Menu 6
LStick joystick button 8 LStick押し込み 1
LStickH/LStickV X-Axis/Y-Axis LSlick 1
★RStick joystick button 9 RStick押し込み 10
★RStickH/RStickV 4th-Axis/5th-Axis RSITICK 10
★DPAD 6th-Axis/7th-Axis 十字キー 8
Trigger 3rd-Axis 左右トリガー(アナログ) 11および14

ただし、上記表の★印のキー 「DPAD(8)」、および「右スティック(10)」がHoloLens実機では反応しませんでした。

Dpadに関しては、joystick button 11もしくは11st-axisを割り当てると何らか値は戻ってくるのですが、法則がわかりません。

また、GetButtonUP()/GetButtonDown()もイマイチまともに動かない。現時点ではかなり怪しい実装の気がします。

いろいろ試したのですが、うまくいかないので、そのうち治ることを期待して、十字キー(DPAD)と右スティックは使わないようにしています。

動作テストの際に作成したスクリプトも貼り付けておきます。 gist.github.com


という事で、いろいろ納得いかない状況ですが、時が解決するかもしれません。 また、知識がない中、調べながら書いたので、誤りや解決のヒント等ありましたら是非、コメントください。


参考サイト