HoloLens 2 公式チュートリアル「Mult-user capabilities tutorials」を試してみた [後編]

# はじめに
本記事は、__[HoloLens 2 公式チュートリアル「Mult-user capabilities」を試してみた [前編]](https://qiita.com/Futo_Horio/items/d1b828db2aeadaa46288)__ の続き、後編記事となります。今回は、前半のチュートリアルで行った成果物を流用しつつ手順を進めていくので、まだ前半部分のチュートリアルがお済みでない方は、先に前半のチュートリアルを完了させることをお勧めいたします。

公式チュートリアルは、__「[Multi-user capabilities tutorials (en-us)](https://docs.microsoft.com/en-us/windows/mixed-reality/mrlearning-sharing(photon)-ch3?WT.mc_id=MR-MVP-5003868)」__ をご覧ください。

#検証環境

- __開発用PC ( Windows 10 Pro )__
  - Windows 10 SDK ( 10.0.18362.0 )
  - Unity 2019.2.21f1
  - Unity モジュール : ユニバーサル Windows プラットフォームビルドサポートモジュール
  - Unity モジュール : IL2CPP ビルドサポートモジュール
  - AR Foundation 2.0.2 ( Package Manager )
  - PUN2 - FREE ( Pun : 2.18.1 / Photon lib : 4.1.4.1 )
  -Visual Studio 2019 ( Version : 16.6.1 )
- __Microsoft HoloLens 2__
- __事前登録済み Azure アカウント__ ( ※ 無料枠でも可能 )

## 公式チュートリアルの手順

今回は、後半のステップ2つの手順について解説をしていきたいと思います。

1. <font color="#cccccc">__Setting up Photon Unity Network__</font>   
— Photon 事前セットアップ
2. <font color="#cccccc">__Connecting multiple users__</font>   
— マルチユーザー間での接続
3. __Sharing object movements with multiple users__   
— 複数デバイス間でのオブジェクト共有
4. __Integration Azure Spatial Anchors into a shared experience__  
— シェアリングの仕組みに ASA を統合する

今回、最後のステップでマルチユーザー間のCGの位置合わせに __「Azure Spatial Anchors ( Azure Mixed Reality サービス ) 」__ を使用する予定ですが、Azureアカウント作成済みの状態からの解説となります。まだ、Azureアカウントをお持ちでない方は、以下よりアカウント登録を済ませておいてください。

## 詳細手順の解説

## 3. Sharing object movements with multiple users

第3章では、オブジェクトの操作を複数人で共有し、相互にインタラクションが可能なコンテンツを作成していきます。他人が操作したオブジェクトの動きをリアルタイム (低遅延) で共有することが可能です。

### 3-1. シーンの準備
プロジェクトウィンドウにて、__Assets > MRTK.Tutorials.MultiUserCapabilities > Prefabs__ フォルダを開きます。 __TableAnchor__ プレハブを選択し、ヒエラルキーウィンドウ上の __SharedPlayground__ オブジェクトへドラッグ＆ドロップし、子オブジェクトとしてシーンへ追加します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/146b7456-4caf-d861-a94c-fd741697ab5e.png" width="600">

### 3-2. オブジェクトのインスタンスを生成するためのPUN設定
このセクションでは、第2章で作成したプロジェクトにて RocketLancher_Complete_Variant Prefab を使用するための設定を行い、プレハブのインスタンス化を行う場所を定義していきます。

プロジェクトウィンドウにて、__Assets > MRTK.Tutorials.MultiUserCapabilities > Resource__ を開きます。

ヒエラルキーウィンドウで、__NetworkLobby__　オブジェクトを展開し、__NetworkRoom__ オブジェクトを選択後、インスペクターウィンドウにて __Photon Room (Script)__ の設定を変更します。

- __Photon User Prefab__ フィールド へ __「PhotonUser」__ プレハブをドラッグ＆ドロップ操作で追加します。
- __Rocket Launcher Prefab__ フィールド へ __「RocketLauncher_Complete_Variant」__ プレハブをドラッグ＆ドロップ操作で追加します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/5f4bf03e-1f34-3372-4dff-3b7540347bde.png" width="600">

子オブジェクト __NetworkRoom__ を選択した状態で、__TableAnchor__ オブジェクトを展開し、インスペクターウィンドウにて、__Photon Room (Script)__ の設定を変更します。

- __Rocket Launcher Location__ フィールド へ TableAnchor の子オブジェクトである __Table__ をドラッグ＆ドロップし追加します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/5ccfc659-fc29-4fe4-ac41-a41007387b9c.png" width="600">

以上で、第3章の手順は終わりとなります。

### 3-3. オブジェクトの動きを共有してみる

それでは実際にアプリケーションの挙動を確認してみましょう。第2章と同様の手順でビルドしたアプリケーションを HoloLens 2 をデプロイし、アプリケーションを起動した後、Unity Editor 上でゲーム再生を行うと HoloLens 2 と Unity Editor でコンテンツのシェアリングが正常に動作することが確認できます。( 実際に動かした際の動画は以下をご覧ください )

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">HoloLens 2 公式チュートリアル<br>Multi-user capabilities (3/4)<br><br>同一コンテンツを複数人で<br>同時に操作できるデモ<br><br>Unity Editor / HoloLens 2 で<br>操作した内容を Photon PUN 経由で<br>リアルタイム共有 (低遅延)<a href="https://twitter.com/hashtag/MRTK?src=hash&amp;ref_src=twsrc%5Etfw">#MRTK</a> <a href="https://twitter.com/hashtag/MixedReality?src=hash&amp;ref_src=twsrc%5Etfw">#MixedReality</a><a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/HoloLens?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens</a> <a href="https://twitter.com/hashtag/Photon?src=hash&amp;ref_src=twsrc%5Etfw">#Photon</a> <a href="https://t.co/BLYXkeN1pc">pic.twitter.com/BLYXkeN1pc</a></p>&mdash; Futo Horio (@Futo_Horio) <a href="https://twitter.com/Futo_Horio/status/1269996004801011714?ref_src=twsrc%5Etfw">June 8, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## 4. Integrating Azure Spatial Anchors into a shared experience

第4章では、Azure Spatial Anchors (ASA) を使って、複数人で共有するオブジェクトの位置合わせを行う手順を解説していきます。これを使うことで、複数人で同じ位置に配置されたCGコンテンツを同時に楽しむことができるようになります。

<font color="red"> __※ Azure Spatial Anchors は Unity Editor 上で動作しません。本章での成果物の挙動を検証する場合は、少なくとも2台の HoloLens にアプリケーションをデプロイする必要があります。__ </font>

### 4-1. シーンの準備
ヒエラルキーウィンドウで、__「SharedPlayground」__ オブジェクトの子オブジェクトである __「TableAnchor」__ を展開します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/340583b3-2cca-e14a-61c9-4323a66c864d.png" width="600">

プロジェクトウィンドウにて、__Assets > MRTK.Tutorials.MultiUserCapabilities > Prefabs__ フォルダへ移動し、__Buttons__ プレハブをドラッグ＆ドロップし、 __TableAnchor__ の子オブジェクトとして追加します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/8e4c6219-81e8-3b6d-a784-ca88b7d9a7e9.png" width="600">

### 4-2. シーンを操作するためのボタン設定
上記で設定した __Buttons__ プレハブを使って、シーンを操作するための設定を追加していきます。

ヒエラルキーウィンドウにて、__Buttons__ オブジェクトを展開し、最上部の子オブジェクトである　__StartAzureSession__ を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/95b78954-78c1-a48b-5e3d-f3bbb25e6915.png" width="600">

インスペクタウィンドウにて、__Interactable (Script)__ コンポーネント内にある __OnClick()__ イベントへ以下の設定を追加します。

- __None (Object)__ フィールドに、__TableAnchor__ オブジェクトを割り当てます。
- __No Function__ドロップダウンから、__AnchorModuleScript > StartAzureSession()__ Function を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/6d0b95c7-112c-62d1-30a4-066a56e6d75c.png" width="400">

ヒエラルキーウィンドウにて、__Buttons__ オブジェクトを展開、上から2番目の子オブジェクトである　__CreateAzureAnchor__ を選択し、インスペクタウィンドウにて、__Interactable (Script)__ コンポーネント内にある __OnClick()__ イベントへ以下の設定を追加します。

- __None (Object)__ フィールドに、__TableAnchor__ オブジェクトを割り当てます。
- __No Function__ドロップダウンから、__AnchorModuleScript > CreateAzureAnchor()__ Function を選択します。
- __None (Game Object)__ フィールド表示が追加されるので、__TableAnchor__ オブジェクトを割り当てます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/ffb01dee-f7bd-9f64-9a0a-0b1be52fb669.png" width="400">

ヒエラルキーウィンドウにて、__Buttons__ オブジェクトを展開、上から3番目の子オブジェクトである　__ShareAzureAnchor__ を選択し、インスペクタウィンドウにて、__Interactable (Script)__ コンポーネント内にある __OnClick()__ イベントへ以下の設定を追加します。

- __None (Object)__ フィールドに、__TableAnchor__ オブジェクトを割り当てます。
- __No Function__ドロップダウンから、__SharingModuleScript > ShareAzureAnchor()__ Function を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/521a8101-816f-2760-303d-5212910eb961.png" width="400">

ヒエラルキーウィンドウにて、__Buttons__ オブジェクトを展開、上から4番目の子オブジェクトである　__GetAzureAnchor__ を選択し、インスペクタウィンドウにて、__Interactable (Script)__ コンポーネント内にある __OnClick()__ イベントへ以下の設定を追加します。

- __None (Object)__ フィールドに、__TableAnchor__ オブジェクトを割り当てます。
- __No Function__ドロップダウンから、__SharingModuleScript > GetAzureAnchor()__ Function を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/27451c02-2f96-f502-85c3-c4ad0c259d06.png" width="400">

以上で、各ボタンをクリックした際の処理の設定が完了しました。

### 4-3. シーンを Azure Spatial Anchors と紐づけ
続いて、Azure Spatial Anchors のアカウント設定を追加していきます。

ヒエラルキーウィンドウにて、__SharedPlayground__　オブジェクトを展開し、__TableAnchor__ オブジェクトを選択します。そして、インスペクターウィンドウへ移動し、__Spatial Anchor Manager (Script)__ コンポーネントの __Credentials__ セクションに接続情報を追加します。( ※ Azure Spatial Anchors のアカウント作成方法については、[こちら](https://qiita.com/Futo_Horio/items/c8fe6b99f5bdc0dd72ac#02-azure-spatial-anchors-%E3%81%AE-account-id-primary-key-%E3%81%AE%E5%8F%96%E5%BE%97)をご覧ください。)

- __Spatial Anchors Account ID__ フィールドに、Azure Spatial Anchors アカウントID を入力
- __Spatial Anchors Account Key__ フィールドに、Azure Spatial Anchors アクセスキーを入力

※ アクセスキーは、Primary と Secondary の2種類ありますが、どちらを入力しても動作するようです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/394085d9-49b1-a8d1-1105-874b53655897.png" width="600">

また、ヒエラルキーウィンドウで __TableAnchor__ を選択したまま、インスペクターウィンドウ上の以下コンポーネントを有効化設定します。

- __Spatial Anchor Manager (Script)__ コンポーネントにチェックを入れ、有効化
- __Anchor Module Script (Script)__ コンポーネントにチェックを入れ、有効化
- __Sharing Module Script (Script)__ コンポーネントにチェックを入れ、有効化

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/2c8b0418-7d33-338b-8dbb-5ea407e7e906.png" width="400">

以上にて、第4章での設定手順は完了です。お疲れさまでした。

### 4-4. 空間配置共有を試してみる

それでは、本チュートリアルの集大成となる Azure Spatial Anchors を活用した空間位置合わせのデモアプリを動かしてみましょう！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">HoloLens 2 × Photon を使った<br>複数人でのシェアリング試してみた。<br><br>Azure Spatial Anchors を使って、<br>物理空間でのオブジェクト位置合わせ<br><br>同一コンテンツを低遅延で共有できるのは、<br>AR体験の没入感向上につながる。<a href="https://twitter.com/hashtag/HoloLens2?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens2</a> <a href="https://twitter.com/hashtag/MRTK?src=hash&amp;ref_src=twsrc%5Etfw">#MRTK</a><a href="https://twitter.com/hashtag/AzureSpatialAnchors?src=hash&amp;ref_src=twsrc%5Etfw">#AzureSpatialAnchors</a><a href="https://twitter.com/hashtag/Photon?src=hash&amp;ref_src=twsrc%5Etfw">#Photon</a> <a href="https://twitter.com/hashtag/MixedReality?src=hash&amp;ref_src=twsrc%5Etfw">#MixedReality</a> <a href="https://t.co/axXaDswiHK">pic.twitter.com/axXaDswiHK</a></p>&mdash; Futo Horio (@Futo_Horio) <a href="https://twitter.com/Futo_Horio/status/1273546598799118336?ref_src=twsrc%5Etfw">June 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<br/>

複数デバイス ( Microsoft HoloLens 2 ) で、Spatial Anchors を共有する手順は以下の通りです。
以下手順に従って操作することにより、Azure Spatial Anchors を使った、複数デバイス間でのコンテンツ位置合わせを行うことができます。
 
1. HoloLens (ユーザー1) : __アプリケーションを起動__ ( Rocket Launcher オブジェクトが生成、表示される )
2. HoloLens (ユーザー2) : __アプリケーションを起動__ ( Rocket Launcher オブジェクトが生成、表示されるが、オブジェクトの同期、空間の位置合わせは行われず )
3. HoloLens (ユーザー1) : __Start Azure Session ボタンを押下__
4. HoloLens (ユーザー1) : __Create Azure Anchor ボタンを押下__ ( TableAnchor オブジェクトの場所にアンカーを作成し、Azure Spatial Anchors リソースへアンカー情報を格納します。 )
5. HoloLens (ユーザー1) : __Share Azure Anchor ボタンを押下__ ( アンカーIDを他のユーザーとリアルタイムに共有。 )
6. HoloLens (ユーザー2) : __Start Azure Session ボタンを押下__
7. HoloLens (ユーザー2) : __Get Azure Anchor ボタンを押下__ ( Azure Spatial Anchors リソースに接続し、共有アンカーIDのアンカー情報を取得。取得したアンカー情報を元に、TableAnchor オブジェクトの位置を移動させます。 )


## お疲れさまでした！
このチュートリアルでは、Azureの強力な Spatial Anchors を統合して、複数デバイス間での共有体験を調整する方法を学ぶことが出来ました。

今回で利用した Photon PUN 無料アカウントの場合、同時接続ユーザー数や、メッセージ送信数などの制約がありますが、シェアリングの体験をサクッと試してみたいという方にお勧めのチュートリアルです。

最後までお読みいただき、ありがとうございました :clap:

## Appendix  : Official Tutorials 
Microsoft HoloLens 2

- [Getting started tutorials](https://docs.microsoft.com/en-us/windows/mixed-reality/mrlearning-base?WT.mc_id=MR-MVP-5003868)
- [Azure Spatial Anchors tutorials](https://docs.microsoft.com/en-us/windows/mixed-reality/mrlearning-asa-ch1?WT.mc_id=MR-MVP-5003868)
- [Azure Speech Service tutorials](https://docs.microsoft.com/en-us/windows/mixed-reality/mrlearning-speechsdk-ch1?WT.mc_id=MR-MVP-5003868)
- __<font color="red">[Multi-user capabilities tutorials](https://docs.microsoft.com/en-us/windows/mixed-reality/mrlearning-sharing(photon)-ch1?WT.mc_id=MR-MVP-5003868)</font>__