HololensでSharingするアプリケーションをスタンドアロンで検証する（エミュレータのみ版）

#　Hololens複数台で同一空間内で動作させるアプリケーションをどう試すか
Hololensで実現できることの1つに複数台で同一空間内でアプリケーションを協調して動作させるものがあります。HoloToolKitでは「Sharing」という機能になります。これを利用するとHololens同士で相互接続するためのサーバをたてて（HoloToolkitに付属）、各Hololensと通信を行い相互に影響を与えるアプリケーションなどを構築することができます。
2/4(土)開催「[Osaka HoloLens Meetup vol.1](https://hololens.connpass.com/event/47003/)」のなかでは「[holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)」を体験しました。自分の頭の上に自機がいてほかの人に向かって弾をうって遊ぶものなのですが複数台だと単独でのアプリとは違った体験ができます。
いざこの手のアプリを作りたいと思っても実際どう確認するかが問題になると思います。なにせHololensが複数台いるのでよっぽどのブルジョアな人か好きな人集まってアプリ作るとかしないと確認が難しいかと思います。
いろいろ試した結果、実機持ちはあまり使わないEmulatorを利用することでSharingのアプリケーションを検証する環境が作れたので紹介します。
実際に動いてる状態では以下のような感じになります。
![s12.png](https://qiita-image-store.s3.amazonaws.com/0/152548/50bac973-e797-9c32-0efa-e91e72b7e9d4.png)



## 環境

今回記載している内容については以下の環境での話になります。

### お題となるアプリ

- [holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)

サイトに行くとZipファイルで圧縮されたものが手に入ります。GitHubからは「[https://github.com/Microsoft/HolographicAcademy/](https://github.com/Microsoft/HolographicAcademy/)」

### 必要なアプリ

必要なアプリについては以下の通りです。なお、エミュレータがHyper-V機能を利用するためProにしています。
おそらくですがエミュレータのVHDを持ってくればほかのVMでもできるかもしれません（未検証）
なお、Hololens Emulator自体は1台あたり2GB通常使います。今回試した方法の中で1GBでも動かせることが分かったので、マシンに8GB搭載されていれば同じ環境を作ることは可能です。

- Windows 10 Pro(Hyper-V機能の有効化必須)
- Visual Studio 2015 Community Edition update 3
- Unity 5.5.0P2 Personal
- Hololens Emulator 10.0.14393.0

## 実施手順
大まかな実施手順は以下の通りです。

1.エミュレータの準備&amp;IPアドレスのチェック
2.SharingServiceの動作確認&amp;IPアドレスのチェック
3.[holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)の修正
4.[holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)のビルドとパッケージ化
5.アプリケーションのデプロイ
6.実行

### 1.エミュレータの準備&amp;IPアドレスのチェック
Visual Studioからデバックで起動できるHololens Emulatorですが仕組み的にはXDEというアプリを経由してHyper-V上のモバイルVMにリモートアクセスして制御する仕組みです。今回はこのエミュレータを複数使うのでVisual Studioからではなく直接コマンドとしてたたいて複数のエミュレータを起動します。
<dl>
<dt>
実行例
</dt>
<dd>"c:\Program Files (x86)\Microsoft XDE\10.0.14393.0\xde.exe" /name "Hololens1" /createDiffDisk "c:\Emulator\Hololens1\Hololens1.vhd" /vhd "C:\Program Files (x86)\Windows Kits\10\Emulation\HoloLens\10.0.14393.0\flash.vhd" /video 1268x720 /memsize 1024 /language 409 /bootlanguage 409 /sku HDE
</dd>
</dl>

起動するとこのようなエミュレータが起動します。主な操作方法はマウスで視線移動。W：前、D：後、A：左、D：右、F2：メニュー表示です。
![s2.png](https://qiita-image-store.s3.amazonaws.com/0/152548/e82e00c5-1928-bcee-786f-f99f0f1aaf99.png)

#### エミュレータの準備
今回は2台分のエミュレータを用意します。

#### 使用するコマンドの説明
```
"c:\Program Files (x86)\Microsoft XDE\10.0.14393.0\xde.exe"
```
コマンドライン引数については今回使用するものだけを列挙しています。

| 引数 | 説明 |
|:-:|:--|
| /name  | VM名。Hyper-Vの仮想マシン名  |
| /vhd | VMのベースイメージ。エミュレータはこのイメージの差分として構築される。後述の/createDiffDiskとセットで設定。  |
| /createDiffDisk | VMの差分イメージファイル。アプリケーションのインストールなどユーザの変更した情報は/VHDで設定したイメージの差分としてこのオプションで指定したVHDに保存される。  |
|/videos|画面の解像度。Hololensの場合は1268x720で設定。|
|/memsize|VMのメモリサイズ。Visual Studioから起動するHololens Emulatorは2GB。今回は1GBで起動。|
|/language|OSの言語。Hololensなので英語のIDである「409」を設定|
|/bootlanguage|起動時のメッセージの言語。Hololensなので英語のIDである「409」を設定|
|/sku|エミュレータの種別。HololensはHDE固定。なお、Windows Phoneの場合はWP8を指定。|

### 設定

<font color="Crimson">赤字</font> は任意の値を設定それ以外は固定で入力してください。初回については1.のコマンドを実行してください。前回の設定状態をそのまま実行する場合は2の手順を実行してください。1.は新しいVMをHyper-Vマネージャーに登録しエミュレータを起動するコマンドになります。すでにある場合は上書き登録するので、設定がリセットされます。なお、Visual StudioからHololens Emulatorを起動すると1の方を呼んでいるようです。

<dl>
<dt>
1.新規にVM名<font color="Crimson">Sample</font>で<font color="Crimson">C:\Emulator\Samples\Sample.vhd</font>を作成、メモリ<font color="Crimson">1GB</font>の英語環境のHololens用仮想OSを作成しエミュレータを起動するコマンド</dt>
<dd>&gt; "c:\Program Files (x86)\Microsoft XDE\10.0.14393.0\xde.exe" /name "<font color="Crimson">Sample</font>" /createDiffDisk "<font color="Crimson">C:\Emulator\Samples\Sample.vhd</font>" /vhd "C:\Program Files (x86)\Windows Kits\10\Emulation\HoloLens\10.0.14393.0\flash.vhd" /video 1268x720 /memsize <font color="Crimson">1024</font> /language 409 /bootlanguage 409 /sku HDE
</dd>
<dt>
2.VM名<font color="Crimson">Sample</font>をメモリ<font color="Crimson">1GB</font>の英語環境でHololens用仮想OSをエミュレータで起動するコマンド。
</dt>
<dd>&gt; "c:\Program Files (x86)\Microsoft XDE\10.0.14393.0\xde.exe" /name "<font color="Crimson">Sample</font>" /video 1268x720 /memsize <font color="Crimson">1024</font> /language 409 /bootlanguage 409 /sku HDE
</dd>
</dl>

### IPアドレスのチェック
SharingServiceとして起動するサーバのIPアドレスとHololens EmulatorのIPアドレスを揃える必要があるためエミュレータのIPアドレスを確認します。エミュレータのメニューからOpen Device Potalを選択しDevice Potalを開きます。「Networking」を選択しIPアドレスを確認します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/fd70d42a-b6da-61a7-8096-1b2ac1701f29.png)



### 2.SharingServiceの動作確認&amp;IPアドレスのチェック

SharingServiceが起動するかの確認します。Unity起動して[holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)開き「HoloToolkit‐Sharing‐24」‐「Launch Sharing Service」を選択しても起動できますが、今回はコマンドで起動。コマンドプロンプトから以下のコマンドを実行。

```
 [展開先フォルダ]\Holograms-240\Completed\Assets\HoloToolkit-Sharing-240\Sharing\SharingService\SharingService.exe -local
```
起動するとサーバのIPアドレスが出カされるので先のエミュレータのIPアドレスと同じセグメントのものがある事を確認しそのアドレスを覚えておきます。
特に何か変更していなければ同一セグメント上でつながるはず。
![s3.png](https://qiita-image-store.s3.amazonaws.com/0/152548/0e411bdd-f75e-80cf-a745-5f174c2e8eb7.png)

### 3.[holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)の修正
次にHololensにインストールするクライアントアプリの修正を実施します。
Unityを起動して展開した[holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)の中にあるCompletedフォルダを開きます。
プロジェクトが開いたら「Hiarachy」で「Sharing」を選択。「Inspector」-「Sharing Stage(Script)」内の「Server Address」に先のSharingServiceを起動した際のIPアドレスを設定します。ここで登録するIPアドレスはHololens Emulatorで登録されていたIPアドレスと同一セグメントのものを入力します。

![s5.png](https://qiita-image-store.s3.amazonaws.com/0/152548/dec1e8e8-08e5-a97e-c192-926f6e913258.png)

次にUWP用のソースを生成します。「File」-「Build Settings」を選択し設定画面を開き設定を行った上で「Build」を実行します。出力先は任意です。
![s6.png](https://qiita-image-store.s3.amazonaws.com/0/152548/bfd023c5-a7e7-6952-872f-2021aed310f3.png)

| 設定箇所 | 設定値 |
|:-:|:--|
| Scenes In Build  | Sharing にチェック |
| Platform  | Windows Store  |
| SDK  | Universal 10  |

### 4.[holograms_240](https://developer.microsoft.com/en-us/windows/holographic/holograms_240)のビルドとパッケージ化
UnityでUWP用のソースコードの出力が無事におわれば、あとはUWPアプリケーションのビルドとパッケージ化を実施します。パッケージ化したものを
Hololens EmulatorにDevice Portal経由でインストールします。

#### UWPアプリケーションのビルド

UnityでUWP用ソースコードを出力したフォルダ内のソリューションをVisual Studioで開きとりあえず正常にビルドが通ることを確認します。
問題がなければ、「SharedHolograms」プロジェクトを選択しポップアップメニューより「ストア」-「アプリ　パッケージの作成」を選択します。
するとパッケージ作成ウィザードが表示されます。「Windowsストアにアップロードするパッケージを作成しますか」は「いいえ」で進めます。
次へ進めると生成時の構成を設定がでてきますので、「任意の出力先」先を選択し構成マッピングを「X86」-「Release(X86)」のみにして「作成」を押下します。
![s8.png](https://qiita-image-store.s3.amazonaws.com/0/152548/725761ff-951b-c84e-a357-a27d04ceaaa5.png)

### 5.アプリケーションのデプロイ
パッケージが作成できたらHololens EmulatorのVMにアプリをデプロイします。「1.エミュレータの準備&amp;IPアドレスのチェック」の手順で2台のエミュレータを起動します。
それぞれのエミュレータが起動したらメニューより![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/5ee8df34-ce9c-464d-122d-28e2743b2e4e.png)「Open Device Portal」を選択しポータルを表示します。
ポータルのメニューから「App」を選択しコンテンツの下部のInstall appの「App package」、「Dependency」を以下の通り設定します。

| 設定項目 | 値 |
|:-:|:--|
|App Package|SharedHolograms_X.X.X.X_x86.appxbundle[^1] |
|Dependency | Microsoft.NET.CoreRuntime.1.0.appx[^2]|
| Dependency  | Microsoft.VCLibs.x86.14.00.appx[^2]|
[^1]: 先のパッケージ作成先として指定したパス直下のものを選択
[^2]: 先のパッケージ作成先として指定したパス内のDependencies/x86内にあるものもを追加

![s9.png](https://qiita-image-store.s3.amazonaws.com/0/152548/6d5cdbe2-a912-f427-57bd-f0309459e652.png)

デプロイに成功すると![image.png](https://qiita-image-store.s3.amazonaws.com/0/152548/7bea05a1-5f88-82e6-d24b-c168b00109f7.png)となります。
メニューにSharedHologramsが追加されます。

### 6.実行
手順「2.SharingServiceの動作確認&amp;IPアドレスのチェック」で使ったSharingServiceを起動します。

```
 [展開先フォルダ]\Holograms-240\Completed\Assets\HoloToolkit-Sharing-240\Sharing\SharingService\SharingService.exe -local
```

起動確認後、二台のエミュレータ上の「SharedHolograms」を実行するとアプリが起動しそれぞれの端末から相手の自機が見えて検証できます。


## 次にやっておきたいこと
以上でSharingアプリケーションのチェック自体はできるのですが、エミュレータの使い勝手が悪いです。基本キーボード操作なので（xboxのコントローラー使えるようなのでそれでやれば幾分マシかも）。よって片方はHololens実機を利用した環境も作りたいなと思ってます。課題になりそうなものは以下の2点。

- ネットワークの構成
- エミュレータと実機の空間情報の統一

エミュレータと実機の空間情報については、Device Portal経由で何かできそうな気がしてます。実機で実空間の空間情報を取得してその情報をエミュレータにインポートみたいなことを考えてます。実機とエミュレータでの検証も試してみたいと思います。