CrossRoad

XRを中心とした技術ブログ。 Check also "English" category.

Holographic Academyの解説とTips紹介「Hologram 101」

====
2017/2/4 追記

Chapter 6のSpatial Mappingでチュートリアル通りに動かなかった箇所が解決したので、動作確認の動画を追加しました。

====

Microsoftでは、「Holographic Academy」というDeveloper用のページがあります。ここには、ゼロからHoloLens開発を始める人向けに、相当細かく手順が書かれています。

なお、HoloLensのアプリ開発を進めやすくするため、Microsoftからは必要なソースコード、Prefab、シェーダなどをまとめた、HoloToolkitも公開されています。

GitHub - microsoft/MixedRealityToolkit-Unity: Mixed Reality Toolkit (MRTK) provides a set of components and features to accelerate cross-platform MR app development in Unity.

ただし、Holographic Academyでは機能別に解説しており、Unity標準のAPIがすぐにわかるように記述されているので、HoloToolKitを読む前にソースコード理解を兼ねてAcademyを試してみるのも良いと思いました。

そこで、今後HoloLensアプリ開発の勉強を兼ねて、まずはHolographic Academyの「Hologram 101」を解説してみました。

0. はじめに

HoloAcademyの最初の二つ、「Holograms 100: Getting started with Unity」と、「Holograms 101E: Introduction with Emulator」は、以前書いた内容とかぶるので省略します。

HoloLensのエミュレータを起動し、Unityでアプリを作るまでの手順とTips紹介 - CrossRoad

また、Holo Academyに記載されている手順はかなり丁寧なので、手順そのままで理解に困らなかった場所については、今回のHologram101以降についても説明を簡略化する予定です。

さて、今回は「MR Basics 101 - Complete project with device - Mixed Reality | Microsoft Docs」の内容を解説します。

1. 準備

MR Basics 101 - Complete project with device - Mixed Reality | Microsoft Docs」を開き、プロジェクトをダウンロードします。

Requires Unity 5.5と書いてある通り、開発環境はUnity5.5にします。

5.5からは、HoloLens向けビルドが正式サポートされているので、なるべく5.5に合わせることをお勧めします。指示にしたがってプロジェクトをUnity5.5で開けばOKです。

なお、全てのAcademyコンテンツを開くと、完成版のUnityプロジェクトと、チュートリアル用に抜けている(例:スクリプトが入ってない)Unityプロジェクトの二つがあります。チュートリアル通りにやってもうまくいかない場合は、完成版を使うことでも動作確認ができるようになっています。

2. Chapter 1 - "Holo" world

これは以前HoloLensのエミュレータ環境構築とほぼ同じ、いわゆるHelloWorld的な流れが書いてあります。大雑把に言うと、以下の手順でアプリをHoloLensにデプロイできます。

  • UnityでHoloLens向けのアプリを作る
  • Build SettingsでPlatformを「Windows Store」、SDKを「Universal 10 」に変更
  • Project Settingsで、Virtual Reality Supportedにチェックをつける
  • Buildして、Visual Studioのプロジェクトを出力する
  • Visual Studioでx86、Deviceに指定して出力

3. Chapter 2 - Gaze

これは、Unityの機能だけでGaze(見つめる)の機能を実装しています。


gistcffb3ab2a2cc0caa1d2902201669366b

25行目でUnityのMain CameraからRaycastを飛ばし、29行目でオブジェクトにヒットしたときにCursorオブジェクトを表示させています。

また、32行目でCursorオブジェクトの表示位置を指定しています。実行すると、GemaObjectに視線を合わせたときだけドーナツ状のカーソルが表示されます。これはわかりやすいですね。

4. Chapter 3 - Gestures

これは、AirTap操作をしたとき、カーソルで選択したGameObjectにイベントを発行することができます。チュートリアルでは、AirTapでSphereを選択すると、Sphereが落下します。


gist37fb4586fec8562e16b8b9bfa58496e4

ここでの肝はGestureRecognizerクラスです。これは、冒頭のusing UnityEngine.VR.WSA.Inputの中にあり、Unity5.5で追加されました。
(Unity Script Referenceの5.4では見つかりませんでした)

WSA = Windows Store Application で、Windows Holographic用のAPIと思われます。21行目のtappedCountでタップ操作を検出し、26行目のSendMessageUpwardsで、対象のGameobjectに付いているOnSelectメソッドを呼び出す準備をしています。

あとは、Update関数の中でRaycastを使ってGameObjectを検出し、先ほどのTappedEventでSendMessageUpwardsを発行します。なお、Unity Script Referenceの説明によると、StartCapturingGestures が呼ばれてからTappedEventを発行できるようです。また、一度イベントを発行すると、StopCapturingGesturesを呼んでいます。都度初期化して使うようですね。

最後に、26行目で発行したOnSelectメソッドですが、これはOnSelectメソッドを持つGameObjectに作用します。このサンプルではSphereCommands.csに書かれています。


gist962fcae8d97d8d24d60f3eb744bd73f0

OnSelectメソッドが呼ばれると、AddComponentでSphereにrigidbodyを付加します。そのため、Sphereが落下します。サンプルシーンでは、collisionDetectionModeを指定することで、SphereにCollisionを指定しています。そのため、Unityで作ったplaneにぶつかるとはね返ります。

5. Chapter 4 - Voice

これを使うと、音声認識をさせることができます。この音声認識エンジンは、Windows10のUWPで使えるものと同じです。この辺は少しだけですが、以前のブログで紹介したことがあります。

【2018/1/22更新】【Unity】公式アセット「Speech-to-Text」の使い方とTips紹介 - CrossRoad

チュートリアルでは、"Reset world"と発声するとsphereが元の位置に戻ってきて、"Drop sphere"と発声すると、sphereが落下します。ここでは、SpeechManager.csで処理を実行しています。


gist7643a95e1fede12182601bac42ebb859

ここでの肝は、9行目のKeywordRecognizerです。これはUnity5.4から搭載された、UnityEngine.Windows.Speechのクラスの一つです。10行目で認識したい言葉と、System.Actionを対応づけるためにDictionaryを定義し、13行目からのStartメソッドで言葉とイベント駆動させたいメソッドを定義しています。

次に、32行目でKeywordRecognizerのインスタンスを生成し、35行目で発生させたいメソッドを登録して、36行目で音声認識を開始しています。最後に、18と26行目で発行したOnResetとOnDropメソッドですが、これもGestureの章で使ったSphereCommands.csに追加します。


giste9e5a3f03ddbd5e21f3cb7e712f47a58

27行目のOnResetでrigidbodyコンポーネントを取り去り、sphereの位置を最初の位置に戻しています。41行目のOnDropはGestureの章で使ったOnSelectを呼ぶことでボール落下を実現しています。ちなみに、SpeechManager.csのStartメソッドで好きな言葉を登録し、keywordRecognizer.OnPhraseRecognizedで実行させたいメソッドを登録すれば、好きな言葉で音声認識ができます。

また、HoloLens自体は2017/1/29時点で日本語非対応ですが、Speech to Textであれば、ローマ字で記述しておくことで、擬似的に日本語を認識させることができます。実際に試したところ、日本語の文字を指定した場合、例えば"小さく"、"ちいさく"のような場合は認識してくれませんでしたが、"kaiten"のようにローマ字入力したら認識してくれました。

そのときのソースコードを参考までに貼りました。


gistec1db09a7f32e85cfa9288ef52393a72


gist8745b2f3e202d7082a29462b5d4b941c

以前、下記の記事ではWindows 10で"生麦生米生卵"をローマ字表記にして認識されたので、ローマ字表記は割とありだと思います。

【Unity】Cortana認識結果を利用してUWP→Unity関数を呼ぶ方法 - CrossRoad

6. Chapter 5 - Spatial sound

ここではサウンドエフェクトの鳴らし方、立体音響の制御方法を解説しています。VRでも同様ですが、立体音響は没入感を高めるためにはとても重要です。また、Audio in mixed reality - Mixed Reality | Microsoft Docsの詳細ページによると、最後の方に以下の記述がありました。

Window's spatial sound engine only supports 48k samplerate for playback. Most middleware programs, like Unity, will automatically convert sound files into the supported format, but when using Windows Audio APIs directly please match the format of the content to the format supported by the effect.
引用元:Audio in mixed reality - Mixed Reality | Microsoft Docs

どうやら、HoloLensでは48kのサンプルレートでの再生のみがサポートされているようです。UnityでHoloLensアプリを作るにはUnityが自動調整してくれるので問題ありませんが、UWPでWindows Audio APIを呼ぶ場合、使う音源のサンプルレートを48kに合わせておく必要があります。

この章ではWindows Holographic 特有のAPIを使うソースコードの記述はなく、Unityで3D音源を使うときの設定をするだけです。

設定後の画面です。

Unityで3D音源を使うときの設定画面

ここで、プラグインをMS HRTF Spatializerに指定します。

Unityで3D音源を使うときの設定画面でMS HRTF Spatializerに指定

OrigamiCollectionオブジェクトに、AmbienceのWavファイルをdrugすると、AudioSourceコンポーネントが自動的に追加され、Ambienceのwavファイルも設定されます。

このサンプルでは二つの機能を体験できます。1つめは空間音響そのものです。HoloLensでアプリを実行すると、和風の音楽が流れます。

Origamiに近づくと音が大きく鳴り、Origamiの後ろ側に立つと、後ろで鳴っているように聞こえます。また、Origamiから遠ざかると音が小さくなります。

二つめは、OnCollisionEnter、OnCollisionStay、OnCollisionExitを利用して音を鳴らす例です。AirTapか音声認識によってSphereを転がすと、衝突間近と転がる時(衝突するとき)に連続的に音が鳴ります。

7. Chapter 6 - Spatial mapping

先ほどのSpatial Sound の章とは異なり、これは100%HoloLens特有の話です。ここでは大きく2種類の機能を説明しています。

(1) wireframeの描画

サンプルシーンに準備されているSpatial MappingというPrefabを使うことで、HoloLensを通した実空間をメッシュ表示して重ねて見ることができます。

アプリを動かしてからsphereをAirTapすると、sphereが転がり落ちて、目の前の床に転がります。


(2) OrigamiのGameObjectを動かす

ここでは、Stage にTapToPlaceParent.csを追加しています。


gist45b84fc58f92a86ae0b40f5acacf3737

9行目のOnSelectを呼ぶ、すなわち、StageをAirTapした場合、placingのフラグがtrueになります。これにより、Update内の処理が連続的に実行されます。

38-44行目の処理では、raycastが連続的に実行されており、ここで取得した位置にStageオブジェクトを移動させています。

もう一度AirTapすると、12行目の処理によりToggle処理が働き、Update内の処理が実行されなくなるので、Stageオブジェクトが止まります。

しかし、私がチュートリアル通りに進めた時は、StageをAirTapしても何も起きませんでした。
サンプルプロジェクトに同梱されていた完成版を使ったらStageオブジェクトを動かすことができたので、何かの手順が抜けているとは思うのですが、、
後日再確認してみようと思います。

====
2017/2/4 追記

@dy_karous さんのご指摘で直してみたら動きました。@dy_karous さん、ありがとうございます。

動かすと、こうなります。

====

8. Chapter 7 - Holographic fun

最後は、Sphereを転がした時に別のオブジェクトを表示させる例です。こちらもOnCollisonEnterを使っています。ボールがOrigamiに衝突すると何かが起こります。

タイトルにfunとあり、何が起こったかを動画でも見せていないので、ここでも詳細は書かないことにします。確かに、ちょっと意外で面白い感じでした。

9. Chapter - The end

このチュートリアルによってできるようになったことを紹介しています。特に解説することがないので省略します。

10. 終わりに

今回、自分の理解も兼ねてソースコードの内容解説や、UnityでのAPIとの関係性を追加してみました。なお、今回の「Hologram 101」ではHoloTool kitの話は出てきませんでしたが、「Hologram 210」以降ではHoloTool kitを使うことが前提となるので、HoloToolKitの使い方も徐々に覚えていきたいと思います。