HoloLens ミートアップで紹介されたMixed Reality Toolkitのあれこれについて

#Hololens ミートアップがcluster内で実施

定期的に開催されるTokyo Hololens ミートアップですが昨今の事情を加味してVR空間での実施となりました。その中でなんとMRTKのDEVチームのYoonさんが登壇されました。資料などの情報は以下の通り公開されています。興味がある方はぜひ確認してください。今回はその中から、MRTKのアップデート状況について紹介があったのでその内容を整理して補足しながら紹介したいと思います。

* イベント全体
[![B3kqRGPWzqc](http://img.youtube.com/vi/B3kqRGPWzqc/0.jpg)](http://www.youtube.com/watch?v=B3kqRGPWzqc)

* Yoonさんの登壇部分
[![08Jy7EsO93c](http://img.youtube.com/vi/08Jy7EsO93c/0.jpg)](http://www.youtube.com/watch?v=08Jy7EsO93c)


## MTRKの今後のアップデート内容の紹介とUXデザインのヒントを紹介

YoonさんはMRTK含めてMixed Reality関連のUXデザインに携わっている方で今回はMRTKの今後のアップデートを含めて新しい機能の紹介をしていただけました。
内容を整理すると大きくは以下のようなカテゴリで有益な情報を提供していただけました。

* 開発を容易にするためのツール/設定
* 試験的導入/新機能紹介
* UXデザインのヒント

以下、調査した内容を含めて紹介したいと思います。基本的にはYoonさんの紹介されている内容がしゅになりますので、各機能の動きなどはYoonさんの動画でぜひ確認してみてください。

### 開発を容易にするためのツール設定 + テクニック

MRTKで提供されているUX関連の機能については現在下のような種類で用意されています。MRTKも長い間の進化で豊富な機能が備わっておりますます便利になっていっています。また、MRTK V2からは設計方法がより簡単な形へ変化しており、それの伴ってツールの使い勝手の向上が行われています。今回はそのいくつかを紹介していただきました。

#### UI Toolbox

MRTK V2では、ボタンなどいくつかのコンポーネントは既に構成済みで提供されています。非常に便利なのですが、現状はボタンの大きさなどをコンポーネント名で判断するしかなく、形状を確認するためには実際に貼り付けるか、サンプルプロジェクトを開いて確認する必要がありました。
この不便さを解消するために、UIをプレビュー表示しながらその中から選択して追加するための仕組みが「UI Toolbox」として追加されています。
以下はそのハードコピーです。右側にあるように各UIコンポーネントごとにカテゴライズされた外観が表示されるようになっています。開発者はここから使いたいコンポーネントを選択することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/58b4ae01-f9d5-3673-6583-62b2efac92f2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a1197f79-a44c-3f24-c057-6e50b707f226.png)

これらの機能は、現在、以下のpull requestで検討が進んでいます。

* [MRTK Toolbox #7176](https://github.com/microsoft/MixedRealityToolkit-Unity/pull/7176)

#### ボタンのアイコン・表題の設定が容易になった

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/3af73c48-7ea6-2f6a-6df0-300d582b0c9a.png)

PressableButtonHoloLens2という、押しボタン式のUIコントロールについての改善機能です。このボタンは上記の通り「アイコン」と「表題」を開発者で変更することができます。
従来は、ボタンオブジェクトの中のラベル要素やアイコン要素を探し出して設定する必要がありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/c4d6bde8-91da-8ca1-b4a7-69e894c4234c.png)

上記は実際のPressaableButtonHoloLens2のコンポーネントの構成になりますが、テキストやアイコンは以下のコンポーネントの設定を変更する必要があります。

* SeeItSayItLabel内のTextMeshPro
* IconAndText内のTextMeshPro
* IconAndText内のUIButtonSquareIcon

これからはこれらの設定を容易にするための[Button Config Helperコンポーネント]が提供されます。上記で個別に設定した情報を纏めて設定できるHelperになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/313b2c78-2efe-ffe3-20b8-9d712bbc8ab7.png)

このような感じでそれぞれのコンポーネントを探して設定しなくてもいいのですごく楽になります。また、OnClickもあるのですが、これについては、Interactableコンポーネントに設定されている値をおなじものになります。

#### リモートデバッギング

Unity Editor上で動作確認をするためにHolographic Remotingを利用することができます。
最近のHolographic RemotingはGaze以外ににもHand TrackingやEye Trackingにも対応するようになりました。そして、使ったことある人なら経験がある安定性。。。
知らなかったのですが実はUSBの有線接続で利用することができるそうです。使い方としては簡単で、HoloLensのWifi接続を切断した状態でPCとUSBで接続します。そうすると、Holographic RemotingのIPアドレスローカルのものになるそうです。この状態で実行すると優先で安定して利用することができるとのこと。


### 試験的導入/新機能紹介

新しく追加されたコンポーネントや機能は以下の通りです。試験的な機能の一部は過去調べたことがある機能もあるので参考にリンクも張っています。

#### UIコントロール

追加されたものや外観が変わったものなど幾つかのコントロールとコレクションが追加されています。

* Rdio Button
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/41bf4c69-aa91-dd95-fa7d-be9b13acd3e6.png)

* CheckBox
* Toggle Swtich
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/6c79c771-d88a-48f2-eada-da2a4b989a91.png)


CheckBoxとSwtichは以前からあったのですが、外観がPressaableButtonHoloLens2とは異なっていてデザインとして少し違和感がありました。今回の対応でデザインの統一感が出せるようになるので、非常にありがたいです。

* Scrolling Collection(試験的な実装)

Scrolling Collectionはこれまでにデモでもよくあったスクロール操作をジェスチャーで実施するためのものです。これまでのものはテクスチャをスクロールすることができます。このCollectionを用いることで3Dオブジェクト自体をスクロールさせることが可能になります。使い方は、従来のCollection系の部品と同じようにオブジェクトをリスト化して利用します。

#### InterractableToggleCollection, InterractableOnToggleReciever

CheckBoxは基本的には複数設置して性別などの選択などに使うものです。つまり、複数のチェックボックスで1つのパラメータを扱うことになります。このためにチェックボックスをグループ化して扱うための[InterractableToggleCollection]が提供されています。
このコレクションにグループ化したいチェックボックスを登録します。この結果、チェックボックスのグループ化が行われて、ボタンを排他で制御できるようになります。
チェックボックスの選択に関するイベントはRecieverを利用します。
Toggle系のRecieverとして、InterractableOnToggleRecieverが提供されています。これによって選択状態と非選択状態にイベントが発生するようになっています。

#### 今後非推奨になるかもしれない機能(リファクタリングによりクラス名が変更になったもの) + 強化された機能

以下の2つについては、リファクタリングの結果機能が名前に合わなくなったのでリネームされています。当面はリファクタリング前の機能もそのまま残るそうです。

* BoundingBox → BoundsControl
* ManipulationHandler → ObjectManipulator

BoundingBoxについては、名称変更が主ですが、ObjectManipulatorについては、以前の機能から大幅に強化されています。最も注目すべきは空間メッシュとの衝突を考慮できるようになった点です。以前のManipulationHandlerはホールド状態でうごかしていても、空間メッシュをすり抜けて操作できてしまいます。いわゆるオブジェクトがめり込む現象が発生しこの結果オブジェクトが見えなくなります。最悪の場合、埋まったオブジェクトを操作することができない。という事態にもなりかねません。

![ObjectManipulator.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/5e06b9a2-72ad-3b05-c8c4-36c8388d2094.gif)

上記のGIFはデモシーンとして提供されているもいのです。ガラス状の壁に阻まれてオブジェクトが動き回るのが確認できます。ObjectMnipulatorは空間メッシュに衝突するようになるのでオブジェクトが埋まるということがないです。
なお、必要かどうかは別にして以前と同じように動作させるためには、対象のコンポーネントからRigidBodyを削除すればOKです。

設定については次のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/9cd895a7-a337-5232-200a-927e460bcf0f.png)

|パラメータ|説明|設定|
|:-:|:--|:--|
|Host Transform|操作対象になるオブジェクト|-|
|Manipulation Type|操作方法。|<ul><li>One Handed</li><li>Two Handed</li></ul>|
|Allow Far Manipulation|遠距離での操作|True</li><li>False</li></ul>|
|One Hand Rotation Mode Near|Rotationの基準を設定|<ul><li>Rotate About Object Center</li><li>Rotate About Grab Center</li></ul>|
|One Hand Rotation Mode Far|Rotationの基準を設定|<ul><li>Rotate About Object Center</li><li>Rotate About Grab Center</li></ul>|
|Two Handed Manipulation Type|両手操作時のオブジェクトの操作対象要素|<ul><li>Move</li><li>Rotate</li><li>Scale</li></ul>|
|Constraints|操作時にオブジェクトの動作制約の設定。軸に制約をかけて上下左右の移動の制限するなど。|<ul><li>FaceUserConstraint</li><li>FixedDistanceConstraint</li><li>FixedRotationToUserConstraint</li><li>FixedRotationWorldConstraint</li><li>MaintainApparentSizeConstraint</li><li>MoveAxisConstraint</li><li>RotationAxisConstraint</li><li>TransformConstraint</li><li>MinMaxScaleConstraint</li></ul>|
|Release Behavior|操作完了時のオブジェクトの挙動を設定。操作完了時の速度や角速度を維持してオブジェクトに力を加えることができます。|<ul><li>Keep Velocity</li><li>Keep Angulrar Velocity</li></ul>|
|Smoothing Active|オブジェクトの動作をスムーズにするか。以下も3つの情報を利用していわゆる追従の緩急を調整することができます。|<ul><li>True</li><li>False</li></ul>|
|Move Lerp Time|オブジェクトのMove時のLerpパラメータの調整。数値が大きい方がゆっくり追従する。|0.001|
|Rotate Lerp Time|オブジェクトのRotate時のLerpパラメータの調整。数値が大きい方がゆっくり追従する。|0.001|
|Scale Lerp Time|オブジェクトのScale 時のLerpパラメータの調整。数値が大きい方がゆっくり追従する。|0.001|
|On Manipulation Started|操作開始時に発生するイベント|-|
|On Manipulation ended|操作終了時に発生するイベント|-|
|On Hover Entered|オブジェクトにCuesorが当たっているとき発生するイベント|-|
|On Hover Exited|オブジェクトにCuesorが外れたときに発生するイベント|-|


#### SolverにTapToPlaceが追加

TapToPlaceはHoloToolkitの頃からあってわかりやすいところでは、以下のチュートリアルで使っています。ステージの移動を行う際の機能は、TapToPlaceで実現しています。

[MR 共有 250:HoloLens (第 1 世代) とイマーシブ ヘッドセット](https://docs.microsoft.com/ja-jp/windows/mixed-reality/mixed-reality-250?WT.mc_id=MR-MVP-5003104)

この機能はGaze用として提供されていた機能でMRTK V2では一旦外されていたのですが改めて追加されています。HoloLens 2でも利用できるように、Hand Rayにも対応するようになりました。

#### Progress Indicator
いわゆるローディング中に出したりするProgress Indicatorのサンプルです。
サンプルでは現在3つほどのパターンが用意されていました。

![ProgressIndicator.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/128ea4f5-c746-30a2-0199-1a9674505cbb.gif)

#### Hand Coash

以前にも解説したことがありますが、手のゴーストによってジェスチャー操作をデモンストレーションする機能です。
![Handcoach.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/b0d5a39d-d93b-a4f6-b52a-3ee7d32a98b7.gif)

詳細を確認したい方は以下も参考にしてください。

[Mixed Reality Toolkit V2.3.0の追加機能 - Hand Coach、Non-Native Keyboard、Hand Physics Extension Service : Hand Coach](https://qiita.com/miyaura/items/6db816d91c17296bf4e9#hand-coach)

#### Hand Physics Extension Service

以前にも解説したことがありますが、Hand Trackingの指先などにColliderを入れることでオブジェクトに干渉するための機能です。
![HandPhysicsService.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/829fedc2-999e-44f5-f27b-4f5d206b6033.gif)

詳細を確認したい方は以下も参考にしてください。

[Mixed Reality Toolkit V2.3.0の追加機能 - Hand Coach、Non-Native Keyboard、Hand Physics Extension Service : 
](https://qiita.com/miyaura/items/6db816d91c17296bf4e9#hand-physics-extension-service)

#### Scene Understanding

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/2da4d20e-abac-db27-a88b-95f0147ca9da.png)

空間マッピングの情報を利用して空間内のマッピングした情報の分類する機能になります。過去Spatial Understandingとして提供されていた機能によく似ている気がするのでもしかしたらベースの概念は同じなのかもしれないですね。

* [Microsoft DOCS : Scene understanding](https://docs.microsoft.com/en-US/windows/mixed-reality/scene-understanding?WT.mc_id=MR-MVP-5003104)


### UXデザインのヒント

UXデザインとして貴重な情報を共有してもらえました。主にHand Menuに関するものです。

#### より自然なHand Menu表現のための機能追加

Hand Menuは手の平を返す動作で表示されるメニューになります。今までは手の平を返すとある閾値で急に表示されるのですが、このタイミングを緩やかにすることで自然に表示されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/c1f8d657-1efb-6aaa-cd10-695253469983.png)

以下のように少し違いがありました。Onにすると、手の回転に合わせてメニューのRotationが変化するようになっているようです。

|ON|OFF|
|:-:|:-:|
|![FacingCameraOn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/68188e47-8faa-73c4-53de-41f8bfa89cb1.gif)|![FacingCameraOff.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/8d8657c2-85d1-9b28-3e78-b551c1e86b44.gif)|

#### 誤動作の防止機能

Hand Menuには誤動作防止のための機能として以下の設定があります。

* Required Flat Hand
* Use Gaze Activation

2つ目のパラメータはオブジェクトの操作時に手の平を返す動作を偶然行ったことでメニューが出力することを防ぐための仕組みです。

#### メニューの大きさに応じたUX表現

Hand Menuは便利なのですが、設定するメニューが複雑になるにつれ、手のひらに連動すると操作が難しくなる場合があります。

|メニュー要素が少ない|メニュー要素が多い|
|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/c967532e-8e66-3e9f-dd1b-26b3d5fe26de.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/d4751e28-e955-c043-67e9-98ff6c23e19d.png)|

右側のような要素が多い場合、Hand Menuを表示するために手のひらを返した状態でもう片方の指で操作するのがむずかしくなります。両手を同時に操作に使うことは押すボタンがずれるなどのUX体験を損なうことが多いためこれを避けるための工夫が必要になります。
例えば、PalmUpをメニュー表示のきっかけに利用します。表示後はWorld空間にロックする形で構成します。メニューは必要に応じてつまんで移動したり×ボタンで閉じることができます。

## まとめ

先日のYoonさんの登壇内容をもとに補足を交えながらMRTKのアップデート情報を整理しました。タイミング的にそろそろV2.4.0リリースの話も上がってくると思うので色々と情報収集して新たなコンテンツ開発のための準備を進めていきましょう。