Holographic Academyの解説「Hologram 210 - Gaze」

前回に引き続き、Holographic Academyについてです。

前回の「Hologram 101」は、HoloLensの基本機能を網羅したシンプルな例でした。

2XX以降は、それぞれの機能について発展的な使い方を紹介しています。

今回はGaze(見つめる)についてです。




==========

目次

0 準備

1 Chapter 1 - Unity Setup

2 Chapter 2 - Cursor and target feedback

3 Chapter 3 - Targeting Techniques

4 Chapter 4 - Directional indicator

5 Chapter 5 - Billboarding

6 Chapter 6 - Tag-Along

終わりに

==========

0 準備

Holograms 210」を開き、下記の files をクリックしてプロジェクトをダウンロードします。

f:id:Takyu:20170130203438j:plain


Hologram101」が未完の場合、先にChapter2のGazeだけでも確認することをお勧めします。

こちらもご参考ください。

magicbullet.hatenablog.jp


1 Chapter 1 - Unity Setup

Unity settings for HoloLens

101のときとは異なり、ダウンロードしたチュートリアル用のデータはunitypackageで格納されています。

そこで、まずは自分でUnityの新規プロジェクトを作り、名称をModelExplorerとします。

この後のビルド用にUnityの基本設定をします。設定内容は以下の通りです。

f:id:Takyu:20170130205250j:plain

Import art assets

ModelExplorerを開いたら、ModelExplorer.unitypackageをインポートします。

Setup the scene

・Main CameraをHoloToolkitフォルダのprefabと差し替え

・指定モデルを並べる

などを実行します。

f:id:Takyu:20170130224409p:plain


Build the project

これまでの手順と同じようにビルドします。

ただし、なぜか今回はVisual Studioを開いたときにmanifestファイルでTargetDeviceFamilyをWindowsHolographicにしています。

f:id:Takyu:20170201230651p:plain

これをWindows.Universalのままにしてもビルドはできました。

Manifestファイルをxml形式で開くには、manifestファイルを右クリックして出てきた画面で「View Code」をクリックします。

「View」をクリックすれば選択式のmanifestが開きます。

f:id:Takyu:20170201230818p:plain


ちなみに、日本でHoloLensの情報を多数提供されている@yuujiさんのブログによると、Windows Store申請の時に指定されているようです。

WindowsストアにHoloLensアプリをリリースする手順まとめ | develog.holo


なお、今回から Fitbox というオブジェクトを追加しています。これにより、HoloLens実機でアプリ起動すると、いわゆるスプラッシュスクリーンが表示されます。

この画面が出ている時にAirTapを実行すると、アプリのメイン画面が表示されます。


ちなみに、今回のAstroman(宇宙飛行士)は、FitBoxが表示されている方向に出現します。

2 Chapter 2 - Cursor and target feedback


ここからは、Gaze Cursorに関する詳細機能を解説しています。

まず、この章冒頭の説明によると、Cursorの表示ルールは下記のようになっています。

1. 常に表示される

2. 大きすぎず、小さすぎないようにする

3. 他のコンテンツの妨げにならない


手順の概要です。

ここでは、まずManagersという空のGameObjectを作り、そこにGazeManager.csを追加します。

GazeManager.csは、HoloToolkit\Input\Prefabs フォルダの中にあります。

f:id:Takyu:20170204002811p:plain

ただし、ここのGazeManager.csは虫食いになっていて、いくつかの箇所を自分で考えて記述するようになっています。

「問題」には"2.a"と"3.a"あります。これはchapterのことです。

ダウンロードしたサンプルプロジェクトには完成版のソースコードがあります。参考のため、下記に貼りました。


giste17fc1687d5006f282e4ee65c0d12dc8

HoloLensとは関係ありませんが、12行目のToolTipという書き方はUnityエディタの機能です。
これを書いた後に変数を宣言すると、Inspectorパネル上でマウスオーバーした時に説明を表示させることができます。

ここだと、

 [Tooltip("Maximum gaze distance for calculating a hit.")]

と宣言した状態で、Inspectorでマウスオーバーすると、このメッセージが表示されます。

f:id:Takyu:20170201214751p:plain

これはHoloLens関係なく使えるネタなので便利です。

ちなみに、Unityを使われる方には不要な紹介ですが、この辺りのTipsはUnityの安藤さんが書かれた、Unityエディタ拡張の本に色々書かれています。


また、GazeManager.csはSingletonで構成されています。8行目の

 public class GazeManager : Singleton<GazeManager>

のように、Singletonを付加してGenericで宣言することで、別のクラスで、GazeManager.InstanceのようにしてPublic変数やメソッドを使うことができます。

こちらを参照させていただきました。

ジェネリッククラスを使うSingletonの実装方法
nicoco.blog.jp

■Instance変数を使う例
qiita.com


この内容は実質的にUnityの標準機能で構成されており、Hologram101のChapter2 Gazeで使われていたWorldCursor.csと大体同じなので、説明を省略します。


GazeManagerコンポーネントのRayCast Layer Maskからは、TransparentFXのチェックを外します。

下記のようになります。

f:id:Takyu:20170131231649p:plain


次に、HoloToolkit\Input\Prefabsにある、Cursorオブジェクトを配置します。

Cursorオブジェクトには、CursorManager.csを追加します。ここも虫食いになっています。完成版のコードは下記です。


gist19ebea20cafa1c0e94a3d06ea94de766

ここもUnityのRaycastで処理が進んでいます。41行目では、先ほどのSingletonによりGazeManager.Instanceとして、GazaManagerクラスの変数Hitを取得しています。

この後は、Gazeカーソルが何かオブジェクトに当たった時用のカーソルオブジェクト(CursorOnHolograms)を表示し、

何も当たっていない時のカーソルオブジェクト(CursorOffHolograms)を非表示しています。


CursorManagerコンポーネントには、このように子オブジェクトを対応させます。

f:id:Takyu:20170201073843j:plain

この時点でビルドすると、このようになります。


続けて、以下に対応します。

・ManagersオブジェクトにInteractibleManager.csを追加

・AstroManオブジェクトにInteractible.csを追加


InteractibleManager.csは、FocusしたGameObjectに対してSendMessageを発行し、OnGazeEnteredを実行させています。

また、Focusが外れたら同じくSendMessageを発行し、OnGazeExitを実行させています。


gist20315e3c112ba8ef55aa73cfc0cf4893


20から57行目のifの使い分けが少しややこしいですが、ここをうまく作ることで実現しています。



Interactible.csでは、Focusが当たった時にOnGazeEnteredメソッドが呼ばれ、Focusが外れた時にOnGazeExitメソッドが呼ばれます。

f:id:Takyu:20170201233151j:plain

それぞれのメソッドで書かれているMaterialのsetFloatを調整することで、フォーカスしたオブジェクトを少し光らせる、つまりハイライト表示を実現しています。

このようになります。


3 Chapter 3 - Targeting Techniques


ここはGazeカーソルをより安定して頭部の動きに追随させるための調整機能について紹介しています。

作業としては、GazeStabilizer.csをGazeManagerオブジェクトに追加し、GazeStabilizerコンポーネントを使うための修正を追記するだけです。

Chapter2でGazeManager.csのソースコードを紹介した時にすでに書いてあるので、きになる方はソースコード中のコメントの3.aと書かれた記述を参照ください。

GazeStabilizerの調整項目は色々あります。

f:id:Takyu:20170201235040p:plain

今のところカーソル調整を急いでやる必要性がないので今回は検証をパスしますが、そのうち試してみようと思います。

4 Chapter 4 - Directional indicator

これは、見てほしい方向を常に矢印で示す機能です。


具体的には、今回のサンプルプロジェクトについているAstroman(宇宙飛行士)オブジェクトの中にDirectional Indicatorという空のオブジェクトがあります。

ここにDirectional Indicatorスクリプトを追加します。



gistba3143160ed257f17316a99b8f2f2084

まず、矢印の色は19行目で簡単に変更できます。

f:id:Takyu:20170203193427p:plain

Update関数の98行目では、camToObjectDirectionによって、自分(gameobject=Astroman)とCamera(HoloLens被っている人)の方向を算出し、次の行でNormalize(単位ベクトル化)しています。

f:id:Takyu:20170204122517p:plain

あとは、109行目のGetDirectionIndicatorPositionAndRotationで、最終的にUnity標準のLookRotationを呼ぶことで矢印の向きを調整します。

f:id:Takyu:20170204124121p:plain


その後、このようにオブジェクトを追加します。

f:id:Takyu:20170202000031p:plain

ちょっと注意が必要なのが、Inspector上でDrag & DropするDirectional Indicatorがなぜか二つあることです。

f:id:Takyu:20170202000150p:plain


AstroManの子であるDirectional IndicatorのInspectorは、このように何もないのに対し、

f:id:Takyu:20170202000235p:plain

単体でPrefabになっているDirectional Indicatorは、このようにMesh情報を持っているので区別は可能です。

f:id:Takyu:20170202000330p:plain

今回Astromanに追加するのは後者の方です。


実装すると、このようになります。青い矢印(実際は三次元的な円錐形)が、Astromanの中心を指しています。




5 Chapter 5 - Billboarding

これは、常に自分の正面にオブジェクトを向かせる機能です。


やることはシンプルで、事前に準備されているBillBoard.csをAstromanにくっつけるだけです。

BillBoard.csをくっつけたオブジェクトは、常に自分の目の前に配置されます。


gist657c769b3ae2af66fef0c1fa64ea09d2


実装方法はとてもわかりやすく、46行目の

Vector3 directionToTarget = Camera.main.transform.position - gameObject.transform.position;

で、CameraとBillBoard間のベクトルを取得し、

66行目にある、FixedUpdate()内部にある

gameObject.transform.rotation = Quaternion.LookRotation(-directionToTarget) * DefaultRotation;

によって、LookRotationで常にカメラ方向を向くようにしています。

DefaultRotationについては、Awakeで初期位置を取得しています。


このようになります。

この動画だとわかりづらいですが、これまで静止していたAstromanがHoloLensのカメラの向きに応じて、向きを変えています。


このままChapter6を実施する場合は、BillBoardは使わないので削除します。

6 Chapter 6 - Tag-Along

最後の機能は、自分で指定したオブジェクトが常時一定範囲内についてくるものです。


まず最初に、ManagersオブジェクトにGesture Manager.csを追加します。

f:id:Takyu:20170203000251p:plain


次に、Hierarchy ViewでChestButton_Centerを表示します。この言葉を検索すればすぐ出てきます。

f:id:Takyu:20170203000201p:plain

このオブジェクトに、Assets/Scripts以下のInteractibleAction.csを追加します。完成版は下記です。


gistbe76818631aa133e7810764717b4736a


ここでは、39行目でSimpleTagAlongというコンポーネントを呼んでいます。

f:id:Takyu:20170204154623p:plain

SimpleTagAlongは、TagAlongの基本機能を提供しています。

例えば、SimpleTagAlong.csの12行目にあるEnforceDiscanceに設定した値によって、HoloLensとの距離が一定になります。

一定にする距離を初期値の2.0f(=2m)にしているため、近づくと離れていき、遠ざかると近づいてきます。

f:id:Takyu:20170204155324p:plain

次に、ChestButton_Centerに付けたTagalong のPrefabを追加します。これはHologramsフォルダの中にあります。


f:id:Takyu:20170203000118p:plain


実行してみます。



このように、Chest部分をAirTapすると、なんだかかっこいいホログラム(TagAlongオブジェクト)が出てきます。

撮影の都合上あまり動き回れていませんが、自分が動き回ると、TagAlong オブジェクトが付いてきます。
また、距離を一定に保とうとするので、TagAlongオブジェクトに近づくと遠ざかります。


終わりに


今回は「Gaze」という観点でのチュートリアルでしたが、どの機能も重要で、一度は試してみるべきだと思いました。

また、今回からHoloTool kitが出て来ましたが、基本的にはUnity標準機能で実装されているので、Unityに慣れていると理解がしやすいです。


もちろん、HoloTool kitを使えば既にできるものも多いですが、機能を絞ったスクリプトを読み解くと結果的に理解が早まるので、ちょっと遠回りなのは承知の上で、引き続きHolographic Academyの勉強を続けていこうと思います。

広告を非表示にする