MRが楽しい

MRやVRについて学習したことを書き残す

公式チュートリアル「HOLOGRAMS 211 2章」を試してみる

本日はチュートリアルお試し枠です。
HOLOGRAMS 211 2章を実施します。
いつも通り、以下ブログの記事を参考に実施します。
azure-recipe.kc-cloud.jp


参考記事にある通りにチュートリアルを実施します。
ビルドすると、カーソルに新しく左右の矢印が表示されています。
f:id:bluebirdofoz:20170628004740j:plain
指を正面に掲げてタップ操作します。
f:id:bluebirdofoz:20170628004747j:plain
そのまま、指を横に動かすと……。
f:id:bluebirdofoz:20170628004755j:plain
宇宙飛行士が指の動きに合わせてクルクルと横回転します。

今回の追加コードの要点を確認してみます。
・GestureActionr.cs

    [Tooltip("Rotation max speed controls amount of rotation.")]
    public float RotationSensitivity = 10.0f;
(略)
    private void PerformRotation()
    {
        if (GestureManager.Instance.IsNavigating &&
            (!ExpandModel.Instance.IsModelExpanded ||
            (ExpandModel.Instance.IsModelExpanded && HandsManager.Instance.FocusedGameObject == gameObject)))
        {
            /* TODO: DEVELOPER CODING EXERCISE 2.c */

            // 2.c: Calculate rotationFactor based on GestureManager's NavigationPosition.X and multiply by RotationSensitivity.
            // This will help control the amount of rotation.
            rotationFactor = GestureManager.Instance.NavigationPosition.x * RotationSensitivity;

            // 2.c: transform.Rotate along the Y axis using rotationFactor.
            transform.Rotate(new Vector3(0, -1 * rotationFactor, 0));
        }
    }

早速ですが、オブジェクトの回転を行っているコードです。
GestureManager.Instance.NavigationPosition.x で指の横方向の動きの量を取得し、それに合わせて宇宙飛行士を、Y軸を回転軸として回転させています。
このとき、回転に -1 を掛けているのは宇宙飛行士がプレイヤー側を向いているからです。
宇宙飛行士にとってのローカルの回転軸はプレイヤーと逆になります。

因みに GestureManager.Instance.NavigationPosition の取得コードは以下です。
・GestureActionr.cs

  public Vector3 NavigationPosition { get; private set; }
(略)
  void Awake()
  {
      /* TODO: DEVELOPER CODING EXERCISE 2.b */

      // 2.b: Instantiate the NavigationRecognizer.
      NavigationRecognizer = new GestureRecognizer();

      // 2.b: Add Tap and NavigationX GestureSettings to the NavigationRecognizer's RecognizableGestures.
      NavigationRecognizer.SetRecognizableGestures(
                                GestureSettings.Tap |
                                GestureSettings.NavigationX);

      // 2.b: Register for the TappedEvent with the NavigationRecognizer_TappedEvent function.
      NavigationRecognizer.TappedEvent += NavigationRecognizer_TappedEvent;
      // 2.b: Register for the NavigationStartedEvent with the NavigationRecognizer_NavigationStartedEvent function.
      NavigationRecognizer.NavigationStartedEvent += NavigationRecognizer_NavigationStartedEvent;
      // 2.b: Register for the NavigationUpdatedEvent with the NavigationRecognizer_NavigationUpdatedEvent function.
      NavigationRecognizer.NavigationUpdatedEvent += NavigationRecognizer_NavigationUpdatedEvent;
      // 2.b: Register for the NavigationCompletedEvent with the NavigationRecognizer_NavigationCompletedEvent function.
      NavigationRecognizer.NavigationCompletedEvent += NavigationRecognizer_NavigationCompletedEvent;
      // 2.b: Register for the NavigationCanceledEvent with the NavigationRecognizer_NavigationCanceledEvent function.
      NavigationRecognizer.NavigationCanceledEvent += NavigationRecognizer_NavigationCanceledEvent;
(略)
  private void NavigationRecognizer_NavigationStartedEvent(InteractionSourceKind source, Vector3 relativePosition, Ray ray)
  {
      // 2.b: Set IsNavigating to be true.
      IsNavigating = true;

      // 2.b: Set NavigationPosition to be relativePosition.
      NavigationPosition = relativePosition;
  }

  private void NavigationRecognizer_NavigationUpdatedEvent(InteractionSourceKind source, Vector3 relativePosition, Ray ray)
  {
      // 2.b: Set IsNavigating to be true.
      IsNavigating = true;

      // 2.b: Set NavigationPosition to be relativePosition.
      NavigationPosition = relativePosition;
  }

GestureRecognizerクラスはUnityEngine.VR.WSA.Inputパッケージのクラスです。
このクラスが持つ NavigationStartedEvent 関数の relativePosition 引数として指の位置情報が取得できるということですね。
ただし、ここで取得できているのはタップ開始時からの相対位置のようです。

公式チュートリアル「HOLOGRAMS 211 1章」を試してみる

本日から新しいチュートリアルお試し枠です。
HOLOGRAMS 211を実施します。内容としてはHOLOGRAMS 210の続きの形となります。
いつも通り、以下ブログの記事を参考に実施します。
azure-recipe.kc-cloud.jp

参考記事にある通りにチュートリアルを実施します。
アプリをビルドすると、HOLOGRAMS 210同様に、宇宙飛行士が現れます。

ここで宇宙飛行士の胸元にある青丸のカーソルに注目してください。
f:id:bluebirdofoz:20170627015835j:plain
指を正面前に持ってくると……。(宇宙飛行士と重なって手が見えにくいですが)
f:id:bluebirdofoz:20170627015846j:plain
青丸のカーソルが指マークに変わりました。手の認識が視覚的に分かるようになります。

因みに握りこぶしを正面に持ってきた場合は、青丸のカーソルのままであり、認識していないことが分かります。
f:id:bluebirdofoz:20170627015909j:plain
hololensを使ったことがない人にhololensを貸すと、この人差し指を認識させるという事前動作が分かりづらいのか。
タップ操作が上手く行えないという人をよく見ます。
このカーソルを使うと、タップ準備ができているかどうかが、見た目で分かるため、hololens初心者のためのUIとして使えそうです。


今回の新しい技術はこの、指の認識処理ですね。コードを確認してみます。
・HandsManager.cs

    void Awake()
    {
        EnableAudioHapticFeedback();

        InteractionManager.SourceDetected += InteractionManager_SourceDetected;
        InteractionManager.SourceLost += InteractionManager_SourceLost;
    }
(略)
    private void InteractionManager_SourceDetected(InteractionSourceState hand)
    {
        HandDetected = true;
    }

    private void InteractionManager_SourceLost(InteractionSourceState hand)
    {
        HandDetected = false;
    }

・CursorFeedback.cs

    private void UpdateHandDetectedState()
    {
        if (handDetectedGameObject == null || CursorManager.Instance == null)
        {
        return;
        }

        handDetectedGameObject.SetActive(HandsManager.Instance.HandDetected);
    }

重要なのは以下のイベント登録です。
・InteractionManager.SourceDetected += InteractionManager_SourceDetected;
・InteractionManager.SourceLost += InteractionManager_SourceLost;

InteractionManagerクラスはUnityEngine.VR.WSA.Inputパッケージのクラスです。
これが指の検出とロストをイベントとしてキャッチしてくれるようです。

Blenderで3Dモデルを作成する(かんたん講座編その10)

3Dモデリングの学習枠です。今回はレンダリングです。
・かんたんBlender講座(レンダリング
 http://krlab.info.kochi-tech.ac.jp/kurihara/lecture/cg/BlenderWeb_Hayashi/html/lighting.html

講座の通りに実施します。
3DCGでのライト配置に、写真撮影の技術をそのまま流用できるというのは面白いです。
写真撮影のスキルがある人は、直感的に被写体をきれいに見せるレンダリングが作れるということでしょうか。

レンダリングを行い、レンダー表示してみた結果がこちら。
f:id:bluebirdofoz:20170626005938j:plain

サンプルがよくなかったのか、床の影が変な感じになりましたが、それ以外は上々です。
それっぽくなりました。
表情に違和感を感じますが……おそらく目の焦点が合っていないからですね。目のテクスチャはそういった点にも気をつけないとです。

blenderのモディファイアをまとめる(変形)

モディファイアの変形機能について、調べた結果をまとめます。
★マークのものは個人的によく使いそう、または、抑えておくべきと感じた機能です。

●変形
・アーマチュア
 メッシュオブジェクトとアーマチュアを関連付け、ボーンの回転や移動などで変形できるモディファイア。
 モディファイアパネルからも設定できるが、ポーズを付けるには頂点ウェイト設定などが必要となる。
 メッシュオブジェクトとアーマチュアを親子化して自動で生成されるようにした方が簡単である。
 - Blenderモディファイア(Armature)
  http://cg.xyamu.net/Blender/entry283.html
 - アーマチュアモディファイア
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modifiers/Deform/Armature
 - アーマチュアによるアニメーション(その1)
  http://www.blender3d.biz/simpleanimation3dcg_deformed_armatures.html

・成形
 選択した型に合わせてオブジェクトを変形させるモディファイア。
 手軽に球状にしたり、角ばらせたりしてデフォームすることが可能である。
 - Blenderモディファイア(Cast)
  http://cg.xyamu.net/Blender/entry196.html
 - キャストモディファイア
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modifiers/Deform/Cast

・修正スムーズ★
 アーマチュアなどで変形させた後に起伏を低減させて滑らかにするモディファイア。
 メッシュを再構築してスムージングを掛ける事ができる。
 形状を各軸に沿って滑らかにしたい時はSmoothモディファイアを使用する。
 - Blenderモディファイア(Corrective Smooth)
  http://cg.xyamu.net/Blender/entry314.html
 - Blender 2.75: モデリング
  https://wiki.blender.org/index.php/Dev:JA/Ref/Release_Notes/2.75/Modeling

・カーブ
 カーブパスの形状に沿ってオブジェクトを変形させるモディファイア。
 通常では難しい有機的なうねった形状などにデフォームさせるのに向いている。
 - Blenderモディファイア(Curve)
  http://cg.xyamu.net/Blender/entry197.html
 - Curve Deform
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modeling/Curves/Editing/Advanced
 - 超簡単にリボンを作る方法
その1【3DCG(Blender)で日本のアニメ的な表現をする方法まとめ】
  http://ch.nicovideo.jp/Arasen/blomaga/ar473459

・ディスプレイス★
 既存のテクスチャの色によってオブジェクトに凹凸変形を加えるモディファイア。
 地形などを作成するのに役立つ。
 - Blenderモディファイア(Displace)
  http://cg.xyamu.net/Blender/entry208.html
 - Displacement Maps
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Textures/Influence/Material/Displacement
 - [Tips]ポリゴンをテクスチャで変形(ディスプレイスメント)[Displace]
  https://buildinginblender.blogspot.jp/2015/05/tipsdisplace.html#!/2015/05/tipsdisplace.html
 - blenderで地形作成する際に使えそうなアレコレ
  https://sites.google.com/site/mieki256wiki/home/blender_make_ground_tips

・フック
 メッシュの頂点を他オブジェクトの動きや拡大縮小に合わせて操作できるようになるモディファイア。
 - Blenderモディファイア(Hook)
  http://cg.xyamu.net/Blender/entry267.html
 - フックモディファイア
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modifiers/Mesh/Hooks

ラプラシアンスムーズ★
 オブジェクトの形状をできるだけ保持しながら起伏を低減させて滑らかにするモディファイア。
 微細なポリゴンで構成されたオブジェクト表面の荒れを軽減したり、
 シンプルな形状のオブジェクトを元に新しい形状にしたりできる。
 形状をある程度犠牲にして滑らかにしたい時はSmoothモディファイアの方が安易である。
 - Blenderモディファイア(Laplacian Smooth)
  http://cg.xyamu.net/Blender/entry276.html
 -
Blender2.70のラプラシアン変形でちょっと遊んでみた感想【ちょっとしたメモ】
  http://ch.nicovideo.jp/Arasen/blomaga/ar466676
 - 6-8 LaplacianSmooth tutorial Blender ラプラシアンスムーズ - YouTube
  https://www.youtube.com/watch?v=V6Axx0vIQEE

・ラティス
 ラティス(格子)をデフォーム用オブジェクトとして使用し、形状に沿ってオブジェクトを変形させる。
 頂点数の多いハイポリゴンなどを大まかにデフォームさせるのに向いている。
 - Blenderモディファイア(Lattice)
  http://cg.xyamu.net/Blender/entry205.html
 - 【Blender】ラティスの使い方【変形】
  http://blender-cg.net/lattice/

・メッシュ変形
 他のメッシュをデフォーム用のケージとして使用できるモディファイア。
 Latticeモディファイアに似ているが、変形させたいオブジェクトの形状に合わせたケージ作りができる
 このため、細かな変形が可能になる。
 - Blenderモディファイア(MeshDeform)
  http://cg.xyamu.net/Blender/entry261.html
 - メッシュ変形モディファイア
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modifiers/Deform/Mesh_Deform

シュリンクラップ★
 対象オブジェクトをターゲットオブジェクトに対して収縮させるモディファイア。
 人物オブジェクトに沿った服などを作るのに向いている。
 - Blenderモディファイア(ShrinkWrap)
  http://cg.xyamu.net/Blender/entry51.html
 - 【Blenderシュリンクラップの使い方【覚書】
  http://madeinpc.blog50.fc2.com/blog-entry-886.html
 - Shrinkwrap モディファイア
  https://blender.jp/modules/xfsection/article.php?articleid=267

・簡易変形
 オブジェクトにひねり、先細りなどの簡易変形を加えるモディファイア。
 メッシュを曲げたりねじったりすることができる。
 - Blenderモディファイア(SimpleDeform)
  http://cg.xyamu.net/Blender/entry207.html
 - Blender曲げる・ねじる・ひねる
  http://tomomohappy5.blog.fc2.com/blog-entry-44.html
 - 車のタイヤを簡単にモデリングする方法 その1【ちょっとしたメモ】
  http://ch.nicovideo.jp/Arasen/blomaga/ar936444

・スムーズ★
 オブジェクトの起伏を滑らかにしたり、逆に大きくしたりできるモディファイア。
 再分割をせずに滑らかに整えるので頂点の数は変わらない。
 ○ラプラシアンスムーズとの違い
  Factorの値にマイナス値を入力できる
  開いた部分も含め全ての部位をスムージング
  スムージングされた結果、オブジェクトの体積が小さくなる
 - Blenderモディファイア(Smooth)
  http://cg.xyamu.net/Blender/entry206.html
 - 平滑化(Smooth)モディファイア
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modifiers/Deform/Smooth
 - 表面を滑らかにする「スムーズ」設定
  http://blender.u5kun.com/?p=570

・ワープ
 指定箇所を中心にオブジェクトを円周上に巻きつけるモディファイア。
 メッシュのパーツを新しい場所のほうへ歪曲させることができる。
 - ワープモディファイア
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modifiers/Deform/Warp
 - ワープモディファイア【Blenderの便利な機能を超簡単に紹介】
  http://ch.nicovideo.jp/Arasen/blomaga/ar494519
 - 【Blender】湾曲・曲げ・せん断する方法
  http://blender-cg.net/warp-bend-shear/

・波
 オブジェクトが柔らかく波打っているようなアニメーションを簡単に作成できるモディファイア。
 オブジェクトの頂点/コントロールポイントのZ座標に海のようなモーションを追加する。
 - Blenderモディファイア(Wave)
  http://cg.xyamu.net/Blender/entry211.html
 - ウェーブモディファイア
  https://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Modifiers/Deform/Wave

hololensでシェアリングを試してみる

本日早速、会社でシェアリングを試す機会があったので忘れないうちに復習しておきます。
試したのはHoloToolkitに含まれるHoloToolkit-Unity-Testsの「SharingTest」です。

最初に以下から最新版のHoloToolkitを取得します。
github.com

「SharingTest」の実施方法は以下を参照していきます。
github.com

因みにシェアリングのテストについて、以下の3つのテストシーンがあるようです。
・SharingTest.unity
 このテストでは、ネットワーキングに共有プレハブを使用し、カスタムメッセージをクライアントと共有する方法を示します。
 また、クライアント間でワールドアンカーを共有して共有スペースを確立する方法を示します。(by自動翻訳さん)
・RoomAndAnchorTest.unity
 このテストでは、アプリケーション内に新しい部屋とアンカーを作成する方法を示します。
 また、新しいアンカーをアップロードしてダウンロードする方法も示します。(by自動翻訳さん)
・SharingSpawnTest.unity
 このテストでは、シーン内およびネットワーク上のクライアント間で同期オブジェクトを生成および削除する方法を示します。
 (by自動翻訳さん)

今回は会社で試した「SharingTest.unity」を構築してみます。
まずダウンロードしたHoloToolkit-Unity-masterからAssets配下を全てインポートします。
f:id:bluebirdofoz:20170623035816j:plain

以降、手順ページに従って実施します。(by自動翻訳さん+追加補足)
 1.テストフォルダ(Assets/HoloToolkit-Unity-master/Assets/HoloToolkit-Tests/Sharing/Scenes)に移動します。
  f:id:bluebirdofoz:20170623035920j:plain
 2.探検したいテストシーン(SharingTest.unity)をダブルクリックします。シーンが読み込まれます。
  f:id:bluebirdofoz:20170623035932j:plain
 3.「File」- >「Build and Settings」をクリックして「BuildSettings」を開きます。
  f:id:bluebirdofoz:20170623035946j:plain
 4.「Add Open Scenes」をクリックしてシーンを追加します。以下の設定を行います。
  ・Platform - > Windows Store
  ・SDK - > Universal 10
  ・UWP Build Type - > D3D
  ・Unity C# Project をチェック
  f:id:bluebirdofoz:20170623040007j:plain
 5.「PlayerSettings」をクリックしてInspectorを開きます。
  「Windows Store」->「Publishing Settings」->「Capabilities」でシーンに必要な機能をすべて有効にします。
  以下の機能にチェックをしてください。
  ・SpatialPerception
  ・InternetClientServer
  ・PrivateNetworkClientServer
  ・Microphone
  f:id:bluebirdofoz:20170623040036j:plain
  「Windows Store」->「Other Settings」->「Virtual Reality Supported」に「Windows Holographic」を設定します。
  f:id:bluebirdofoz:20170623040026j:plain
 6.「Switch Platform」をクリックして設定を完了します。「Build」をクリックし、Appフォルダを作成します。 
  コンパイルが完了したら、ソリューションを開き、デバイスにデプロイします。
  f:id:bluebirdofoz:20170623040049j:plain

クライアント側のビルドはこれで完了です。
ただ、会社の先輩に教えてもらったところ、6/22現在ImportExportAnchorManager.csに不具合があるようです。

Unity5.6では、Awake関数からWorldAnchorstoreクラスのGetAsync関数を呼ぶと、NullReferenceExceptionになるので、Start関数から呼び出す必要があるそうです。
github.com

よってImportExportAnchorManager.csを以下の通り、修正しておきます。
・ImportExportAnchorManager.cs(修正前)

        protected override void Awake()
        {
            base.Awake();

#if UNITY_WSA && !UNITY_EDITOR
            // We need to get our local anchor store started up.
            currentState = ImportExportState.AnchorStore_Initializing;
            WorldAnchorStore.GetAsync(AnchorStoreReady);
#else
            currentState = ImportExportState.Ready;
#endif
        }

        private void Start()
        {
            // SharingStage should be valid at this point, but we may not be connected.
            if (SharingStage.Instance.IsConnected)
            {
                Connected();
            }
            else
            {
                SharingStage.Instance.SharingManagerConnected += Connected;
            }
        }

・ImportExportAnchorManager.cs(修正後)

        protected override void Awake()
        {
            base.Awake();
        }

        private void Start()
        {
#if UNITY_WSA && !UNITY_EDITOR
            // We need to get our local anchor store started up.
            currentState = ImportExportState.AnchorStore_Initializing;
            WorldAnchorStore.GetAsync(AnchorStoreReady);
#else
            currentState = ImportExportState.Ready;
#endif

            // SharingStage should be valid at this point, but we may not be connected.
            if (SharingStage.Instance.IsConnected)
            {
                Connected();
            }
            else
            {
                SharingStage.Instance.SharingManagerConnected += Connected;
            }
        }

これでクライアントアプリの準備が完了しました。


ついでに最新のHoloToolkitでサーバ側プログラムを用意しておきましょう。
先ほどのプロジェクトで「HoloToolkit」->「Sharing Service」->「Launch Sharing Service」をクリックします。
するとエラーが発生しました。サーバプログラムがないと怒っているようです。
f:id:bluebirdofoz:20170623040221j:plain

SharingService.exeは外部プログラムとして扱われるようになったようで、外部ディレクトリに準備してやる必要があります。
プロジェクトフォルダを開いて、HoloToolkit-Unity-masterからExternal配下を全てコピーします。
f:id:bluebirdofoz:20170623040246j:plain

もう一度「HoloToolkit」->「Sharing Service」->「Launch Sharing Service」をクリックしてみると……。
f:id:bluebirdofoz:20170623040256j:plain
SharingService.exeが起動しました。
このとき、コマンドプロンプトにはサーバのIPアドレスが表示されています。

クライアントアプリにサーバのIPアドレスを教えましょう。SharingオブジェクトのInspectorから設定可能です。
f:id:bluebirdofoz:20170623040310j:plain

SharingService.exeは起動したまま、ビルドを行い、hololensでアプリを起動してみると……。
f:id:bluebirdofoz:20170623040321j:plain
サーバへの接続が行われました。「Sucessfully uploaded anchor」が表示されていれば成功です。
アプリを複数台のhololensに展開して起動するとシェアリングが行えます。

公式チュートリアル「HOLOGRAMS 240」を試してみる

チュートリアルお試し枠です。
今回は少し順番を飛ばして、シェアリングのチュートリアルであるHolograms 240を試します。
いつものページにHolograms 240の記事はないので、公式ページを直接参照します。
・Holograms 240
 https://developer.microsoft.com/en-us/windows/mixed-reality/holograms_240

英語なので公式ページは及び腰でしたが、ある程度分かると動画もある分、こちらの方が分かりやすいですね。
この開発サポートの厚さは流石。hololens開発始めて以降、私の中でMicrosoftの評価が上がる上がる。

まずは「1章 Holo World」を確認しました。
f:id:bluebirdofoz:20170622030607j:plain
アンカー用のオブジェクトを置くだけの内容なので、続けて「2章 Interaction」も確認します。
f:id:bluebirdofoz:20170622030614j:plain
アンカー用のオブジェクトが視線に追従して動きます。
f:id:bluebirdofoz:20170622030626j:plain
タップ操作を行うと、タップを行った位置にオブジェクトが固定されます。

以下のHolograms 101「6章 Spatial mapping」で行った技術と大きな違いはありません。
bluebirdofoz.hatenablog.com

ただ個人的にオブジェクトの追従動作が、カメラの動きに少し遅れてついてくるように改良されていて気に入りました。
・HologramPlacement.cs

    void Update()
    {
        if (!GotTransform)
        {
            transform.position = Vector3.Lerp(transform.position, ProposeTransformPosition(), 0.2f);
        }
    }

    Vector3 ProposeTransformPosition()
    {
        // Put the model 2m in front of the user.
        Vector3 retval = Camera.main.transform.position + Camera.main.transform.forward * 2;

        return retval;
    }

調べてみたところ、特段難しいことをやっている訳ではなく、現在位置と配置予定位置の中央値を取って設定しているようです。

さて、次の「3章 Shared Coordinates」からシェアリングの機能が登場します。
しかし当然ながら仮想空間を共有する他のhololensがないと、機能は体験できません。

ひとまずプログラムを組んでおき、タイミングを見て会社の他のhololensユーザと合わせて試してみることにします。

公式チュートリアル「HOLOGRAMS 210 6章」を試してみる

チュートリアルお試し枠です。
今回はHolograms 210 6章 Tag-Alongを試します。
azure-recipe.kc-cloud.jp

リンク先のページではInteractibleAction.csのリンクが切れていたので、下記から取得しました。
magicbullet.hatenablog.jp

チュートリアルの通りに実装を進め、アプリをビルドしました。
宇宙飛行士にあるボタンををタップするとディスプレイのようなものが浮かび上がります。
f:id:bluebirdofoz:20170621012336j:plain
視線を移動させると、それに追従するようにディスプレイが空間を移動します。
f:id:bluebirdofoz:20170621012349j:plain
宇宙飛行士に近づくと、ディスプレイも奥へと下がります。

追加したコード部分を確認します。
・Interactible.cs

    void OnSelect()
    {
        for (int i = 0; i < defaultMaterials.Length; i++)
        {
            defaultMaterials[i].SetFloat("_Highlight", .5f);
        }

        // Play the audioSource feedback when we gaze and select a hologram.
        if (audioSource != null && !audioSource.isPlaying)
        {
            audioSource.Play();
        }

        /* TODO: DEVELOPER CODING EXERCISE 6.a */
        // 6.a: Handle the OnSelect by sending a PerformTagAlong message.
        SendMessage("PerformTagAlong");
    }

・InteractibleAction.cs

    void PerformTagAlong()
    {
        if (ObjectToTagAlong == null)
        {
            return;
        }

        // Recommend having only one tagalong.
        GameObject existingTagAlong = GameObject.FindGameObjectWithTag("TagAlong");
        if (existingTagAlong != null)
        {
            return;
        }

        GameObject instantiatedObjectToTagAlong = GameObject.Instantiate(ObjectToTagAlong);

        instantiatedObjectToTagAlong.SetActive(true);

        /* TODO: DEVELOPER CODING EXERCISE 6.b */

        // 6.b: AddComponent Billboard to instantiatedObjectToTagAlong.
        // So it's always facing the user as they move.
        instantiatedObjectToTagAlong.AddComponent<Billboard>();

        // 6.b: AddComponent SimpleTagalong to instantiatedObjectToTagAlong.
        // So it's always following the user as they move.
        instantiatedObjectToTagAlong.AddComponent<SimpleTagalong>();

        // 6.b: Set any public properties you wish to experiment with.
    }

今回追加したのは、タップを行うと、ObjectToTagAlongオブジェクトを表示するという処理ですね。
このとき、"TagAlong"というタグが付けられたオブジェクトがゲーム内に存在しないことを確認しています。
これは複数表示するのを防ぐためのものと思われます。

5章で利用したBillboardもアタッチすることでディスプレイが常にカメラ方向に正面を向くようになっています。
このスクリプトはパネルUIの表示に役立ちそうですね。

SimpleTagalongコンポーネントはHoloToolkitに付属するコンポーネントです。
オブジェクトを視線の先にディレイをもって追従します。以下で既に実践利用していますね。
bluebirdofoz.hatenablog.com

これで公式チュートリアル「HOLOGRAMS 210」は完了です。