SHOTech Blog

プログラミングに関する記録です

HoloLens2チュートリアルの補足メモ(前編)

この記事はHoloLens Advent Calendar 2020の16日目の記事となります。

qiita.com

今回はMicrosoftが公開しているHoloLens2のチュートリアルに関する補足的な内容です。

今回やること

docs.microsoft.com

このチュートリアルをやっていきます。
なんで今頃このチュートリアルをやるかというと、社内でHoloLensに興味のある若手にHoloLensの開発を学んでもらうためにこのチュートリアルを実施予定です。そこで説明が必要な部分や、気を付ける部分、詰まりそうな部分を先にピックアップしてメモしておこうかなと思います。

つい先日HoloLens2のDeveloper Editionが発売され今後ますます使ってみる人が増えると思いますので、縁があればそいういった方の参考にもなればと思います。

基本的な手順はチュートリアルの通りなので割愛することもあります。なので、手順そのものはチュートリアルのドキュメントを参照してください。

使用した環境

  • Windows10 Pro
  • Unity2019.4.16f1
  • VisualStudio2019 Community
  • MRTK v2.5

プロジェクトの作成と初期化

docs.microsoft.com

このドキュメントの設定に沿って進めます。

プロジェクトの設定

Tutorialに沿って、Unityで新しくプロジェクトを作成してUWPに変更します。
その後TextMeshPro の重要なリソースをインポートし、続けてMRTK(Microsoft.MixedReality.Toolkit.Unity.Foundation.2.5.1.unitypackage)もインポートします。
f:id:syota-y1989:20201216114846p:plain
MRTKインポート後にMRTK Project Configuratorというこの画面が出た場合は「Apply」をクリックしてください。これによってMRTKを使った開発用の設定を自動でやってくれます。

f:id:syota-y1989:20201216120256p:plain
Project SettingsからPlayer > XR Settingsの順に開いて「Virtual Reality Supported」にチェックを入れます。 Depth Formatは16bitを選択します。その下のEnable Depth buffer sharingにもチェックを入れます。

f:id:syota-y1989:20201216115557p:plain
MRTK Project Configuratorの画面が出たら、Audio Spatializerの項目を「MS HRTF Spatializer」にしてApplyをクリックします。

設定が終わったらProject Settingsの画面を閉じます。

シーンの作成

f:id:syota-y1989:20201216121201p:plain
Unity メニューで、 [Mixed Reality Toolkit] > [Add to Scene and Configure...]の順にクリックしてMRTK用のシーンを追加します。たったこれだけでMRTK用の開発基礎となる最低限のオブジェクトを含んだシーンが作成されます。

ここで一度シーンを保存します。チュートリアルのドキュメントではこの後ビルドをやってますが、ここではスキップします。

MRTK プロファイルのカスタマイズ(空間認識の設定)

docs.microsoft.com

ここからはこのドキュメントに沿って進めます。ここでは空間認識の設定を行います。これによってHoloLensでアプリを起動した後、自動的に空間を認識することができます。

ドキュメントに沿ってMixedRealityToolkit の構成プロファイルを DefaultHoloLens2ConfigurationProfile に変更します。
MRTKを使った開発ではこのプロファイルを複製しながら開発を進めます。(テンプレートとして使ってるオリジナルのプロファイルは編集できないので複製して編集できるようにします。

f:id:syota-y1989:20201216124054p:plain

SpatialAwarenessのEnable Spatial Awareness Systemにチェックを入れ、その後、MixedRealitySpatialAwarenessSystemProfileもcloneします。

f:id:syota-y1989:20201216124735p:plain

Windows Mixed Reality Spatial Mesh Observerセクションの中のプロファイルもcloneします。

f:id:syota-y1989:20201216125108p:plain
Display OptionをVisibleからOcculsionに変更します。

f:id:syota-y1989:20201216154642p:plain
Visibleの場合、空間認識をしたところはこのようにメッシュが表示されます。

f:id:syota-y1989:20201216154914p:plain
このメッシュはMRTK_WireframeというマテリアルがVisibleの時に適応されるためです。 なので、Display OptionをOcculsionに変えることでこのメッシュが表示されなくなり、視界がクリアになります。メッシュが表示されないだけで、空間認識はアプリ起動後に機能しています。

オブジェクトの配置

docs.microsoft.com

ここからはこのドキュメントに沿って進めます。
MRTK.HoloLens2.Unity.Tutorials.Assets.GettingStarted.2.4.0.unitypackageをダウンロードしてインポートします。(ドキュメント内でクリックすればダウンロードできます)
※このアセットはMRTK v2.4の時のものですがそのまま使用します。

f:id:syota-y1989:20201216134602p:plain
Hierarchyで空のゲームオブジェクトを作成し「RoverExplorer」という名前にします。このオブジェクトを使って以降は作業を進めます。
リネーム後は位置を変更します。(設定値はドキュメントを参照)

f:id:syota-y1989:20201216140246p:plain
TableプレハブをHierarchyのRoverExplorerにD&Dで子オブジェクトとして配置し、Transformを調整します。 ( 設定値の情報はドキュメント参照)
※RoverExplorerの上にカーソルを合わせてD&Dすることで直接RoverExplorerの子オブジェクトとして配置できます。

f:id:syota-y1989:20201216135452p:plain
同じようにRoverAssemblyもRoverExplorerにD&Dで子オブジェクトとして配置し、Transformを調整します。( 設定値の情報はドキュメント参照)

f:id:syota-y1989:20201216140616p:plain
RoverExplorerオブジェクトを右クリックしてCreate Emptyをクリックします。これでRoverExplorerの子オブジェクトとして作成します。作成後、名前を変えてTransformの値を調整します。(設定値はドキュメント参照)

f:id:syota-y1989:20201216142446p:plain
ドキュメント中部にあるこの部分は人によっては勘違いしやすいので注意してください。

f:id:syota-y1989:20201216143247p:plain
このようにHierarchyウィンドウで、RoverExplorer⇒RoverAssembly⇒⇒RoverModel⇒ Partsという順で辿り、その中にある

  • Camera
  • Generator
  • Lights
  • UHFAntenna
  • Spectrometer

を複製します。
f:id:syota-y1989:20201216143401p:plain
複製後、はRoverPartsの子オブジェクトとして配置します。配置後は名前の最後にある (1) を _Part に変えます。

f:id:syota-y1989:20201216144611p:plain
RoverPartsオブジェクトにGridObjectCollectionコンポーネントを追加して、ドキュメントに沿って設定値を変更します。
変更後、Update Collectionボタンをクリックして配置完了です。

f:id:syota-y1989:20201216151744p:plain
個のキャプチャの手前表示されてるようにPartsを一列に整列することができました。GridObjectCollectionを使用するとこのようにオブジェクトを簡単に整列させることができます。

補足

f:id:syota-y1989:20201216152635p:plain
今回はGridObjectCollectionの設定値の1つであるsurface typeはplaneを選択していますが、ほかのものを選ぶとこのように形状を変えて整列することができます。

f:id:syota-y1989:20201216152846p:plain
Layoutの設定によって、オブジェクトを並べる順番も変えることが可能です。
詳しくはここを参照してください。

microsoft.github.io

コレクションを使った例はこちら
github.com

Solversを使用した動的なコンテンツの作成

docs.microsoft.com

ここからはこのドキュメントに沿って進めます。
Solvers というのはオブジェクトの位置や回転の設定を簡単にしてくれるもので、例えば、常にカメラの正面にオブジェクトを配置するとか、カメラに追従するようにオブジェクトの位置や向きを変えることができます。
詳しくはこのドキュメントを参照してください。

hololabinc.github.io

Directional Indicator Solverを使う

今回はDirectional Indicator Solverというものを使用して、ユーザを目的の3Dオブジェクトに導くようなものを実装します。

f:id:syota-y1989:20201216191507g:plain
MRTK.Tutorials.GettingStartedのPrefabにあるchevronをHierarchyにD&Dして追加して位置を調整します。(設定値はドキュメント参照)
青い矢印のようなものが出ればOKです。

f:id:syota-y1989:20201216184947p:plain
名前を変えて、AddComponentからDirectionalIndicatorを追加します。
SolverHandlerとDirectionalIndicatorの2つが自動的に追加されていればOKです。

SolverHandlerは追跡対象の参照オブジェクト(メイン カメラトランスフォーム、ハンドレイなど)を設定し処理してくれるものです。ここでは、SolverHandlerのTracked Target TypeがHeadになっていることを確認します。

f:id:syota-y1989:20201216193437g:plain
DirectionalIndicatorコンポーネントのDirectional TargetにHierarchyにあるRoverExplorerをD&Dしてセットします。View Offsetは0.2にします。

f:id:syota-y1989:20201216201034g:plain
実行するとこんな感じで、RoverExplorerオブジェクトが視界から外れるとオブジェクトの方向を向くという動きをします。

SolverHandlerのTracked Target TypeをHeadにしてるため、メインカメラのTransformを基準にIndicatorオブジェクトが動きますが、 ほかの選択肢を選択した場合は以下のようになります。

f:id:syota-y1989:20201216202605g:plain
ControllerRay(ハンドレイの先を基準にする)を使った場合はこうなります。左手のみのキャプチャですが、両手で同じことができます。逆に左手のみや右手のみという設定も可能です。
HandJointにすると特定の指の関節を基準にすることができます。このようにTracked Target Typeを目的や用途によって選択することができます。

Tap to Place Solverを使用する

f:id:syota-y1989:20201216231016p:plain
HierarchyにあるRoverAssemblyオブジェクトにTap To Place (Script) コンポーネントを追加します。

f:id:syota-y1989:20201216231431p:plain
Magnetic Surfaces > Element 0 ドロップダウンから、 Spatial Awareness 以外のすべてのオプションをオフにします。
これにより、オブジェクトを配置するときに Tap To Place (Script) コンポーネントで検出できるオブジェクトが決定します。 この設定を Spatial Awarenessのみに変更することにより、Tap To Place (Script) コンポーネントは、Spatial Awarenessという名前の Unity レイヤーのオブジェクトにのみ Rover を配置できるようになります。レイヤーはオブジェクトのグルーピングをするもので、例えば、特定のレイヤーに配置されたオブジェクトだけをカメラに映したり、特定のレイヤーに配置されたオブジェクト同士のみに対して衝突判定をするようなことができます。
f:id:syota-y1989:20201216231947p:plain
オブジェクトをどのレイヤーに設置するかはInspectorのLayerで決めることができます。

f:id:syota-y1989:20201216233929g:plain
Tap To PlaceコンポーネントのOn Placing Started () イベントに新しくイベントを追加します。HierarchyにあるRoverAssembly オブジェクトをD&Dで設定し、functionはTapToPlace の float SurfaceNormalOffsetを選択します。
引数は0のまま。

f:id:syota-y1989:20201216234649p:plain
Cubeを追加後Transformを変更し、LayerをSpatialAwarenessに設定します。
これでSolverがSpatialAwarenessのLayerに対して正しく動くか確認します。

f:id:syota-y1989:20201216235426g:plain
Cubeを変形した平面にRoverを移動できればOKです。動作確認後はCubeを削除して完了です。

長くなったので今回はここまで。
後編に続く。