Check! HoloLens x Azure Bot Service 連携を試そう！ by Mixed Reality Academy

こんにちは、 @dz_ こと大平かづみです。

Prologue - はじめに
====

Microsoft は、Mixed Reality を学習するコンテンツとして、 [Mixed Reality Academy](https://docs.microsoft.com/en-us/windows/mixed-reality/academy) と銘打って多数のチュートリアルとサンプルコードを提供してくれています。

このうち、_301_ ～ _313_ の項目は _MR and Azure_ としてカテゴライズされており、HoloLens をはじめとした MR とクラウドの連携が今後視野に入ってくると予想されます。

これは、やってみるっきゃない！ということで、 HoloLens も C# も Visual Studio も初心者な私ですが、Azure とつなげてみたいのでこのチュートリアルと試してみることにしました！

- [MR and Azure 312 - Bot integration - Mixed Reality | Microsoft Docs](https://docs.microsoft.com/en-us/windows/mixed-reality/mr-azure-312)

結果としては、無事動きました！(ヾ(｡･ω･)ﾉ

一通りのことに触れられたので、ボリュームは多いですがやってみる価値ありです。

そこで、まだ英語のコンテンツしかないので、簡単な和訳もかねて作業時のメモを掲載します。元のドキュメントと照らし合わせて進めば、最後までできると思います。

ご興味ある方はぜひチャレンジしてみてくださいね！(*'ω'*)

References
----

- [Install the tools - Mixed Reality | Microsoft Docs](https://docs.microsoft.com/en-us/windows/mixed-reality/install-the-tools#installation-checklist-for-immersive-headsets)
- [Unity development overview - Mixed Reality | Microsoft Docs](https://docs.microsoft.com/en-us/windows/mixed-reality/unity-development-overview)

How it works
----
アプリを起動後、青いオブジェクトをタップすると、ボットが起動しユーザーからの音声入力を待機します。
ユーザーの発言を Bot Service に連携させ、その返信をテキストで表示します。

Preparation
====
開発PC
----
### [Unity 2017.4](https://unity3d.com/unity/qa/lts-releases?version=2017.4) のインストール
- LTS で推奨されている
- インストールするときは、デフォルトに加え、 ` Windows Store .NET Scripting Backend` にチェックを入れる

### [Visual Studio 2017](http://dev.windows.com/downloads) のインストール
- ` Universal Windows Platform development` を選択し、カスタマイズを開く
- _Workloads_ タブで `Game Development with Unity` にチェックを入れる
    - Unity が既にインストールされている場合は、 `Unity 2018.1 64-bit Editor` のチェックを外す
- _Workloads_ タブで `ASP.NET and web development` と `Azure development` にチェックを入れる

### `Developer mode` の有効化
- 開発PCの _Settings_ > _Update & Security_ >  _For developers_ で _Developer mode_  にチェックする

Hololens
----
- [Set up HoloLens (HoloLens) | Microsoft Docs](https://docs.microsoft.com/en-us/hololens/hololens-setup)

Microsoft Azure
----

- 有効なAzureアカウント
    - お持ちでない場合は、 こちらから 22,500円のクレジットを含む12か月無料アカウントをご利用ください。
        - [Azure の無料アカウントを今すぐ作成しましょう | Microsoft Azure](https://azure.microsoft.com/ja-jp/free/)

作業メモ（簡単な和訳）
====

以下、作業メモ、兼簡単な和訳です。チャプター番号はあっていますが、細かい連番は一部省略したりしていてあっていません。[元のドキュメント](https://docs.microsoft.com/en-us/windows/mixed-reality/mr-azure-312)対比しながら進めば問題ないかと思います。

1. Visual Studio で Bot Application (C#) を作成する
----

- Chapter 1 – Create the Bot application

1. 新規プロジェクトで、 _.NET Core_ か _cloud_ から、 `ASP.NET Core Web Applicaton` を選択して次へ進む。
1. `ASP.NET Core 2.1` （ドキュメントでは _2.0_ だが、 _2.1_ しかなかった）で `Empty` を選択し、 _Authentication_ は、 `No Authentication` を指定して、プロジェクトを作成する。
1. Nuget パッケージの管理画面から、_Browse_ タブで、 `Include prerelease` にチェックをつけ、 `Microsoft.Bot.Builder.Integration.AspNet.Core` をインストールする。
1. _Solution Exproler_ のプロジェクトを右クリックし、メニューから _Add_ | _Class_ を実行し、 `MyBot` クラスを作成する。
1. 同様に、 `ConversationContext` クラスを作成する。
1. _Sokution Explorer_ の _wwwroot_ を右クリックして、_Add_ | _New Item_ をクリックする。_ASP.NET Core > Web > Content_ から  _HTML Page_ を選択し、 `default.html` と名前を付け、 _Add_ をクリックする。
1. `ConversationContext` クラスをダブルクリックして開き、ドキュメント _1-10_ のように記述する。このクラスには、このボットが会話のコンテキストを管理するために使う変数を持たせる。
1. `MyBot` クラスを開き、ドキュメント _1-11_ のように記述する。このクラスは、ユーザーのアクティビティを受信して呼ばれるハンドラをホストする。
1. `Startup` クラスを開き、ドキュメント _1-12_ のように記述する。このクラスは、ボットの初期化を行う。
1. `Program` クラスを開き、ドキュメント _1-13_ のようになっているか確認する。ただし、 _ASP.NET Core 2.1_  の場合は、 `BuildWebHost` から `CreateWebHostBuilder` に代わっているので、下記を参考に確認する。
  - 参考) [ASP.NET Core 2.1.0-rc1 now available | ASP.NET Blog](https://blogs.msdn.microsoft.com/webdev/2018/05/07/asp-net-core-2-1-0-rc1-now-available/)
1. すべてのファイルの変更が保存されているか確認する。

2. Azureポータルで Azure Bot Service  を準備する
---- 
- Chapter 2 - Create the Azure Bot Service

1. Azureポータルで、 `Web App Bot` を新規作成する。
1. さくせいできたら、 _Channels_ の _Add a featured channel_ で _configure Direct Line channel_ をクリックする。
1. _Secret keys_ が表示されるので、 _Show_ をクリックして文字列を表示し、コピーしておく。

3.  ボットを Azure Bot Service にデプロイする
----

- Chapter 3 – Publish the Bot to the Azure Web App Bot Service

1. Visual Studio に戻って、作成中のプロジェクトを開く。
1. _Solution Explorer_ の _MyBot_ プロジェクトを右クリックし、 _Publish..._ をクリックする。
1. _Pick a public target_ 画面で、 _App Service_ をクリックし、 _Select Existing_ を選択する。右下の _Create_ の下向き矢印から _Create Profile_ を選択する。
1. _Add an account..._ から Azureアカウントでログインする。
1. _App Service_ 画面で、 _Subscription_ を指定し、 下段のリソース一覧から作成した Bot Service を選択し、 _OK_  をクリックする。
1. _Publish_ ボタンをクリックし、デプロイする。（数分かかる）

4. Unity プロジェクトを準備する
----

- Chapter 4 – Set up the Unity project

1. Unity を開く。
1. _Project name_ に任意のプロジェクト名を指定する。テンプレートは _3D_ のままで、必要に応じて _Location_ や _Enable Unity nalytics_ を指定し、 _Create project_ボタン をクリックする。
1. Unity が開いたら、 _Edit_ > _Preferences..._ から _Unity Preferences_ を開き、 _External Tools_ タブの _External Script Editor_ が _Visual Studio 2017 (Community)_ （またはお使いのエディション）に設定されていることを確認する。
1. _File_ > _Buid Settings..._ を開く。
    1.  _Universal Windows Platform_ を選択する。 _Switch Platform_ ボタンをクリックして、反映する。
    1. _Target Device_ に `HoloLens` を指定する。
    1. _Build Type_ に `D3D` を指定する。
    1. _SDK_ に `Latest installed` を指定する。
    1. _Visual Studio Version_ に `Latest installed` を指定する。
    1. _Build and Run_ に `Local Machine` を指定する。
    1. この scene を保存してビルドするために、 _Add Open Scenes_ ボタンをクリックすると、Explorer が立ち上がるので、 `Scenes` という名前の新しいフォルダを作成する。 `Scenes` フォルダに移動し、 _File name_ に `BotScene` を入力して保存する。
1. ひきつづき _Build Settings_ 画面で、_Player Settings_ ボタンをクリックすると、 _Inspector_ にパネルが表示される。そこで、ドキュメント _4-7_ を参考に設定する。
1. _Build Settings_ 画面に戻ると、 _Unity C# Prjects_ という項目が利用可能になっているので、チェックぼっくにチェックする。
1. _Build Settings_ 画面を閉じる。
1. scene とプロジェクトを保存する。

5. Unity プロジェクトでカメラを準備する

- Chapter 5 – Camera setup

1. _Hierarchy panel_ パネルで、 _Main Camera_ を選択する。
1. _Inspector_ パネルに _Main Camera_ のコンポーネント群が表示される。下記を確認、指定する。
    1. _Camera object_ （名前？）が `Main Camera` であることを確認する。（空白や大文字などのスペルに注意）
    1. _Tag_ が `MainCamera` であることを確認する。（空白なしなどスペルに注意）
    1. _Transform Position_ を `0, 0, 0` に指定する。
    1. _Clear Flags_ に `Solid Color` を指定する。
    1. _Background_ の色を `Black(Hex Code: #000000), Alpha 0` に指定する。

6. Unity プロジェクトで、 `Newtonsoft` ライブラリをインポートする
----

- Chapter 6 – Import the Newtonsoft library

1. ドキュメント_Chapter 6_ の _compatible version already organized with the correct Unity folder structure here_ から最適化された _Newtonesoft_ ライブラリをダウンロードする。
2. Unity の _Assets_ > _Import Package_ > _Custom Package..._ をクリックし、上記ライブラリパッケージを読み込む。
3. _Import Unity Package_ 画面で、_Plugins_ 配下の項目にすべ手チェックをつけ、 _Import_ ボタンをクリックする。
4. _Project_ パネルの _Plugins_ > _Newtonsot_ から `Newtonsoft.Json.dll` を選択する。_Inspector_ パネルで、 _Any Platform_ と _WSAPlayer_ のチェックボックスにチェックがついていないことを確認する。
5. _Project_ パネルの _WSA_ フォルダを開き、以下を確認する。
    6. _Any Platform_ のチェックボックスにチェックがついていないこと
    7. _WSAPlayer_ にのみチェックがついていること
    8. _Dont process_  にチェックがついていること

7. Unity プロジェクトで `BotTag` を作成する
----

- Chapter 7 – Create the BotTag

1. _Hierarchy_ パネルの _BotScene_ > _Main Camera_ を選択し、 _Inspector_ の _Tag_ プルダウンから _Add Tag..._ をクリックする。
2. _+_ 記号をクリックし、 _New Tag Name_ に `BotTag` と入力して _Save_ ボタンをクリックする。（ _Main Camera_ には適用しないこと。）

8. Unity プロジェクトで、 `BotObjects` クラスを作成する
----

- Chapter 8 – Create the BotObjects class

1. _Project_ パネルで、 `Assets` フォルダを選択した後、 _Create_ > _Folder_ をクリックし、 `Scripts` フォルダを作成する。
2. _Scripts_ フォルダをダブルクリックして開き、右クリックして _Create_ > _C# Script_ をクリックし、 `BotObjects` というスクリプトを作成する。
3. `BotObjects` スクリプトをダブルクリックがすると、 _Visual Studio_ が開く。_Windows Security Alert_ が表示された場合は、よく確認し  _Allow access_ をクリックする。
4. ドキュメント _8-4_ に従いスクリプトを記述し、保存する。

9. Unity プロジェクトで、 `GazeInput` クラスを作成する
----

- Chapter 9 – Create the GazeInput class

ゲイズ（HoloLens 内で視線により動くカーソルを一点に固定し注目する動作）をコントロールするクラスを作成する。

1. さきほど作成した `Scripts` フォルダの配下で右クリックし、 _Create_ > _C# Script_ で `GazeInput` スクリプトを作成する。
1. `GazeInput` スクリプトをダブルクリックし手開き、ドキュメント _9-4 ~ 8_ に従い記述し保存する。

10. Unity プロジェクトで `Bot` クラスを作成する

- Chapter 10 – Create the Bot class

Bot Service と連携するコアとなるクラス。

1. `Scripts` フォルダに `Bot` スクリプト（_C# Script_）を作成する。
1.`Bot` スクリプトを ダブルクリックして開き、ドキュメント _10-4 ~ 12_ に従い記述し、保存する。
  - `botSecret` には、前述でコピーしておいた _Secret key_ の文字列を指定する。

11. Unity プロジェクトで `Interactions` クラスを作成する
----

- Chapter 11 – Create the Interactions class

HoloLens 内でのタップを検出するクラス。

1. `Scripts` フォルダ内に `Interactions` スクリプトを作成する。（_C# Script_）
2. `Interactions` を開き、ドキュメント _11-4 ~ 7_ に従って記述し、保存する。

12. Unityプロジェクトで `SceneOrganiser` クラスを作成する
----
- Chapter 12 – Create the SceneOrganiser class

1. `Scripts` フォルダはいかに `SceneOrganiser` スクリプトを作成し、開く。
2. ドキュメント _12-4 ~ 7_ に従い記述し、保存する。
3. SceneOrganiser` を _Hierarchy_ の _Main Camera_ にドラッグ＆ドロップする。 _Inspetor_ パネルの _Main Camera_ のコンポーネントとして、 _Scene organiser (Script) _ が表示されていることを確認する。

13. Unity プロジェクトを確認する
----

- Chapter 13 – Before building


14. ビルドする
----

- Chapter 14 – Build and Sideload to the HoloLens

1. _File_ から _Build Settings_を開く。
2. _Build_ ボタンをクリックする。 
3. 保存先を指定するため、 Explorer が開き、プロジェクトフォルダが表示される。 `App` フォルダを作成し、選択した状態で _Select folder_ ボタンをクリックする。

15. HoloLens にデプロイする
----

- Chapter 15 – Deploy to HoloLens

1. HoloLens とリモートデプロイをするため、以下を行う。なお、開発PCと同じ WiFi に接続されているものとする。
    1. HoloLens で、 _Settings_ を開く。
    1. _Network & Internelt_ > _Wi-Fi_ > _Hardware roperties_ を開く。
    1. _IPv4 address_ を確認する。
    1. つぎに、 _Settings_ > Update & Security_ > _For Developers_ を開き、`On` に設定する。
1. Visual Studio で、先ほどビルドした Unity プロジェクトのソリューションファイルを開く。（ `App` フォルダ配下の `.sln` ファイル）
1. _Solution Configuration_ は、 `Debug` を指定する。
1. _Solution Platform_ は、 `x86, Remote Machine` を指定する。すると、 _Remote Connections_ ウィンドウが開き、自動検出が開始される。 _Auto Detected_ に該当する HoloLens が表示された場合はそれを選択する。検出されない場合は、先ほど確認したIPアドレスを指定する。
1. _Build_ メニューから、 _Deploy Solution_ をクリックする。
1. _PIN_ の入力を要求された場合は、 HoloLens の_Settings_ >  _For developers_ > _Pair_ ボタンをクリックすると、PIN番号が表示されるので、それを入力する。

16. HoloLens Bot アプリを触ってみる
----

- Chapter 16 – Using the application on the HoloLens

1. デプロイが完了したら、HoloLenのメニューからアプリを開く。
2. 開いたウィンドウをタップすると起動する。
3. _Listening..._ になる際に、マイクの利用可否の確認ウィンドウが出るので、許可する。

動いたー！！！(ヾ(｡･ω･)ﾉ


Epilogue - おわりに
====

途中でアプリの調子が悪くなった場合は、ブルームすると空のウィンドウが表示されるので閉じることができます。

また、 _Deploy Solution_ ではなく、デバッグを開始するとそのままデバッグできるので何か不備がある場合はお試しください。

Tips
----
- Visual Studio でコメントアウトするショートカットは、 _Ctrl + K, Ctrl + C_ 。コメント解除は _Ctrl + K, Ctrl + U_ 。
- Visual Studio のインテリジェンスは優秀！


以上です！楽しかった！いろいろカスタマイズしたりして、覚えていきたいです。