WinMRで始めるMixed Reality Toolkit Unity - モーションコントローラ使ったアプリ開発のTips

# 先行者泣かせのモーションコントローラ
Windows Mixed Reality Deviceが出たときに開発者版が欲しくて購入した人はかなり泣く出来事ではないでしょうか。せっかく市販でリリースされたにも関わらず、なぜかモーションコントローラ単体での販売がないというお金に糸目をつけなくてもよい人はいいですが、ヘッドセットだけ余らせても悲しいこの事態。今回唯一モーションコントローラを単体で販売している米Dellから個人輸入で手に入れました。そこで、Mixed Reality Toolkit-Unity(以下MTRK)を利用したモーションコントローラの使い方について紹介したいと思います。まずはモーションコントローラを使った開発する際に自分が困って対処療法をはかった部分について説明したいと思います。

## そもそも個人輸入したもの使って大丈夫なのか？
これについては、技適マークが入っているのを確認しています。ですので、場合によっては個別手配でコントローラを手に入れても使うことはできますよ！
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">技適マークありですよ！ <a href="https://t.co/LNEvXa9EdD">pic.twitter.com/LNEvXa9EdD</a></p>&mdash; takabrz (@takabrz1) <a href="https://twitter.com/takabrz1/status/925356388326322181?ref_src=twsrc%5Etfw">2017年10月31日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 開発環境などなど
今回は以下の環境を用意。なお、MTRKについてはモーションコントローラ用のサンプルがあります。値を一通り採取できるようになっていますのでかなり参考になると思います。今回はこのサンプルの中からモーションコントローラの検出と値取得部分の仕組みについてご紹介します。

* Visual Studio 2017 15.2
* Unity 2017.2.0f3
* [MixedRealityToolkit-Unity v1.Dev.2017.2.1](https://github.com/Microsoft/MixedRealityToolkit-Unity/releases/tag/v1.Dev.2017.2.1)

### 注意点！
MRTKについては現状２リリース状態になっています。
[github - Mixed Reality Toolkit -Unity](https://github.com/Microsoft/MixedRealityToolkit-Unity)のトップから入るとHoloLens Developersはこっち使ってねと書かれているので間違えないようにしてください。

* HoloLens向けバージョン：<font color="red">v1.2017.2.0</font>
* WindowsMR向けバージョン：<font color="red">v1.Dev.2017.2.1</font>

## モーションコントローラを扱うにあたってのTips

Windowsストアアプリとして作ってデプロイしてしまえば問題ないのですが、開発デバッグ中に実は結構手間取ったりしていました。私だけかもしれないですが同じように困った状態になる人がいないようにTips残しておきます。個人的にはモーションコントローラで開発すると色々面倒なことがあって少し厄介だなという印象です。

### Windowsストアアプリとして開発しないといけない
MRTKでのモーションコントローラは以下の条件で制御されています。
* UNITY_WSA
* UNITY_2017_2_OR_NEWER

つまり、そのままではいったんビルドしてからでないとモーションコントローラの制御部分の開発できないという状態になりますorz
※面倒なのでUnityエディタから起動したVSのプロジェクトでUNITY_WSAを定数に突っ込んで開発することは可能。

### デバッグ実行が面倒
一応Unityプレーヤで実行はできるんですが、モーションコントローラを使ってデバッグしようとしてもそのままだと認識しないようです。以下の手順でやるとプレーヤーでも動いたので参考にしてください（ほんとはもっと簡単にできるはずなんですが。。。）

1. HMDを接続して開発端末をMixed Reality ポータル状態にする。
2. 開発端末側で「Y」+「Windowsボタン」でMixed Realityポータル状態でも操作できるようにする。
3. Unity Editor上でプレーヤーを起動する。
4. この時点でHMD上ではアプリが動いています。
5. モーションコントローラのWindowsボタンを押す。<br/>いつもの部屋になります。
6. 視野の周辺に青色背景のウインドウがあるはず（Unityプレーヤーから起動したウインドウ）なのでそれをモーションコントローラで選択する。

上記手順を踏むとモーションコントローラがプレーヤの中でも使えるようになります。なぜかプレーヤ起動するだけではモーションコントローラが動かないんですが今のところバグなのかは不明です。

### モーションコントローラ制御値
形状は以下のようなものになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/b42f6982-cab4-2a5f-24c7-58127f323701.png)

モーションコントローラの操作として以下のデータを採取することができます。

| 操作 | 概要 |取得可能値|
|:-:|:--|:--|
| コントローラの情報  | センサー検出範囲内のコントローラの情報を取得できます。|<ul><li>Position</li><li>Rotation</li></ul> |
| ポインターの情報  | センサー検出範囲内で動かしている限りその時点のコントーローラから正面（コントローラの輪の部分に対して垂直方向）へのポインタの情報を取得できます|<ul><li>Position</li><li>Rotation</li></ul>|
| Selectボタン  | 人差し指で操作するトリガー状のボタンです。トリガーのOn/OFFだけでなくOnの間は引き具合によって0~1の値を取得可能です。|<ul><li>引く</li><li>離す</li><li>引き具合(0~1)</li></ul>  |
| Graspedボタン  | コントローラの握るところについているボタンです。  |<ul><li>押す</li><li>離す</li></ul>|
| Menuボタン  | 親指スティックとパッドの間にあるボタンです。  |<ul><li>押す</li><li>離す</li></ul>|
| 親指スティック  | 親指で操作するスティックです。スティックを押すことでボタンとしても機能します。また、基本的にはテレポートやカメラのローテーションに使いますが、無効化しスティックの入力値をアプリとして利用することも可能です。  |<ul><li>引く</li><li>離す</li><li>X軸(-1~1)</li><li>Y軸(-1~1)</li></ul>|
| パッド| 親指スティック横の平らなボタンです。これもスティック同様押すことでボタンとして機能します。また、タッチパッドとしての値も取得可能です。  |<ul><li>押す</li><li>離す</li><li>触れている</li><li>X軸(-1~1)</li><li>Y軸(-1~1)</li></ul>|
| Windowsボタン  | 言わずともわかるWindowsボタンです。これについてはWindowsメニューが出るので検出はできないです。  |-|


### ボタン押下系のイベント
どのボタンでもとりあえず押下したときにイベントとして制御するには以前からあるIInputClickHandlerインターフェースを利用したイベント処理が可能です。
インターフェースメソッドであるOnInputClickedメソッドの引数eventDataからコントローラの情報にアクセスするためのオブジェクトは取得できますので、どのボタンが押されたかなどは制御可能となっています。

## 次回について
MRTKのサンプルにはMotionControllerTestというシーンが用意されており、これを動かすと一通りモーションコントローラについての取得値の確認が行えます。次回はこのシーンで使われている処理を通してモーションコントローラの実装やMRTKでの動作について解説したいと思います。
このほかに、もう少しモーションコントローラ周りの制御を楽にするための制御部品も少しつくったのでGithubへの公開と解説も入れる予定です。