HoloLens (第1世代) 基本 101e: emulator を使用したプロジェクトの完了

重要

mixed reality Academy チュートリアルは、HoloLens (第1世代)、Unity 2017、および mixed reality イマーシブヘッドセットを念頭に置いて設計されています。 そのため、それらのデバイスの開発に関するガイダンスを引き続き探している開発者のために、これらのチュートリアルをそのまま残しておくことが重要だと考えています。 これらのチュートリアルは、HoloLens 2 に使用されている最新のツールセットや相互作用では更新され 、新しいバージョンの Unity と互換性がない可能性があります。 これらは、サポートされているデバイス上で継続して動作するように、保守されます。 HoloLens 2 向けには、新しいチュートリアル シリーズが投稿されています。


このチュートリアルでは、Unity でビルドされた完全なプロジェクトについて説明します。これは、宝石ジェスチャ音声入力空間サウンド空間マッピングなど、HoloLens の主要な Windows Mixed Reality 機能を示しています。 このチュートリアルの完了には約1時間かかります。

デバイス サポート

コース HoloLens イマーシブ ヘッドセット
MR の基本 101E:エミュレーターを使用した完全なプロジェクト ✔️

開始する前に

前提条件

プロジェクト ファイル

  • プロジェクトに必要な ファイル をダウンロードします。 Unity 2017.2 以降が必要です。
    • 引き続き Unity 5.6 のサポートが必要な場合は、 このリリースをご利用ください。
    • 引き続き Unity 5.5 のサポートが必要な場合は、 このリリースをご利用ください。
    • 引き続き Unity 5.4 のサポートが必要な場合は、 このリリースをご利用ください。
  • ファイルをデスクトップまたはその他の簡単な場所に保管します。 フォルダー名は Origami のままにしておきます。

注意

ダウンロードする前にソースコードを確認する場合は、 GitHub で入手できます。

Chapter 1-"Holo" ワールド

この章では、最初の Unity プロジェクトをセットアップし、ビルドとデプロイのプロセスをステップ実行します。

目標

  • Holographic 開発用に Unity を設定します。
  • ホログラムを作成します。
  • 作成したホログラムを確認します。

手順

  • Unity を起動します。
  • [Open] を選択します。
  • 前にアーカイブしていない Origami フォルダーとして場所を入力します。
  • [ Origami ] を選択し、[ フォルダーの選択] をクリックします。
  • 新しいシーンを保存します。 [ファイル / 名を付けてシーンを保存 する。
  • シーンに Origami という名前を 付け 、[保存] ボタンを押します。

メインカメラの設定

  • [Hierarchy](階層) パネル で、 [Main Camera](メイン カメラ) を選択します。
  • インスペクター で、変換位置を 0、0、0 に設定します。
  • " Clear Flags " プロパティを見つけ、ドロップ ダウンから [ 単色] に変更します。
  • [Background](背景) フィールドをクリックして、カラー ピッカーを開きます。
  • R、G、B、A0 に設定します。

シーンをセットアップする

  • [ 階層] パネル で、[ 作成 ] をクリックし、[ 空の作成] をクリックします。
  • 新しい [作成] オブジェクト を右クリックし、[名前の変更] を選択します。 OrigamiCollection オブジェクトの名前を「」に変更します。
  • [ Project] パネル の [ホログラム] フォルダーから次のようにします。
    • ステージ を階層にドラッグして、 OrigamiCollection の子にします。
    • Sphere1 を階層内にドラッグして、 OrigamiCollection の子にします。
    • Sphere2 を階層内にドラッグして、 OrigamiCollection の子にします。
  • [階層] パネル指向性ライト オブジェクトを右クリックし、[削除] を選択します。
  • ホログラム フォルダーから、ライト を [階層] パネル のルートにドラッグします。
  • 階層 で、 OrigamiCollection を選択します。
  • インスペクター で、変換位置を 0、-0.5、2.0 に設定します。
  • Unity の [ 再生 ] ボタンをクリックして、ホログラムをプレビューします。
  • プレビューウィンドウに Origami オブジェクトが表示されます。
  • プレビューモードを停止するには、もう一度 Play を押します。

Unity から Visual Studio にプロジェクトをエクスポートする

  • Unity で、[ファイル > ビルド設定 を選択します。
  • [プラットフォーム] ボックスの一覧の [ Windows ストア] を選択し、[プラットフォームの切り替え] をクリックします。
  • SDKUniversal 10 に設定し、ビルドの種類D3D に設定します。
  • Unity C# プロジェクト を確認します。
  • シーンを追加するには、[開いている シーンの追加 ] をクリックします。
  • [プレーヤー設定] をクリックします。
  • [インスペクター] パネルで Windows ストアのロゴ を選択します。 次に、[設定の発行] を選択します。
  • [ 機能 ] セクションで、 マイクSpatialPerception 機能を選択します。
  • [ビルド設定] ウィンドウに戻り、[ビルド] をクリックします。
  • "App" という名前の 新しいフォルダー を作成します。
  • アプリフォルダー をシングルクリックします。
  • [フォルダーの選択] をクリックします。
  • Unity が完了すると、エクスプローラーウィンドウが表示されます。
  • アプリ フォルダーを開きます。
  • Origami Visual Studio ソリューション を開きます。
  • Visual Studio の一番上のツールバーを使用して、ターゲットをデバッグから リリース に、ARM から X86 に変更します。
    • デバイスボタンの横にある矢印をクリックし、[ HoloLens Emulator] を選択します。
    • [ デバッグ]、[デバッグなしで開始] の順にクリック > 、Ctrl キーを押し ながら F5 キーを押します。
    • しばらくすると、エミュレーターは Origami プロジェクトから開始されます。 エミュレーターを初めて起動するときは、エミュレーターが起動するまでに15分程度かかることがあります。 開始したら、閉じないでください。

第2章-宝石

この章では、最初に3つの方法を使用して、ホログラムと対話する方法を紹介します。

目標

  • 世界でロックされているカーソルを使用して、宝石を視覚化します。

手順

  • Unity プロジェクトに戻り、[ビルド設定] ウィンドウを閉じます (まだ開いている場合)。
  • Project パネル で、ホログラム フォルダーを選択します。
  • カーソル オブジェクトをルートレベルの [階層] パネル にドラッグします。
  • カーソル オブジェクトをダブルクリックすると、詳細が表示されます。
  • Project パネルで Scripts フォルダーを右クリックします。
  • [ 作成 ] サブメニューをクリックします。
  • C# スクリプト を選択します。
  • スクリプトに WorldCursor という名前を指定します。 注: 名前は大文字と小文字が区別されます。 .cs 拡張機能を追加する必要はない。
  • [階層] パネルで Cursor オブジェクト を選択します
  • WorldCursor スクリプトを [インスペクター] パネル にドラッグ アンド ドロップします
  • WorldCursor スクリプトをダブルクリック して、このスクリプトをVisual Studio。
  • このコードをコピーして WorldCursor.cs に貼り付け、 すべて 保存します
using UnityEngine;

public class WorldCursor : MonoBehaviour
{
    private MeshRenderer meshRenderer;

    // Use this for initialization
    void Start()
    {
        // Grab the mesh renderer that's on the same object as this script.
        meshRenderer = this.gameObject.GetComponentInChildren<MeshRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        // Do a raycast into the world based on the user's
        // head position and orientation.
        var headPosition = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;

        RaycastHit hitInfo;

        if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
        {
            // If the raycast hit a hologram...
            // Display the cursor mesh.
            meshRenderer.enabled = true;

            // Move thecursor to the point where the raycast hit.
            this.transform.position = hitInfo.point;

            // Rotate the cursor to hug the surface of the hologram.
            this.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
        }
        else
        {
            // If the raycast did not hit a hologram, hide the cursor mesh.
            meshRenderer.enabled = false;
        }
    }
}
  • [ファイル] からアプリを リビルド>ビルド設定。
  • エミュレーターへのデプロイにVisual Studioソリューションに戻る。
  • メッセージが表示されたら、[すべて再読み込み] を選択します。
  • [デバッグ] - [>デバッグなしで開始] をクリックするか**、Ctrl + F5 キーを押します**。
  • Xbox コントローラーを使用してシーンを見回します。 カーソルがオブジェクトの形状とどのように対話するのかに注意してください。

第 3 章 - ジェスチャ

この章では、ジェスチャ のサポートを 追加します。 ユーザーが紙球を選択すると、Unity の物理エンジンを使用して重力をオンにして球を落とします。

目標

  • [選択] ジェスチャを使用してホログラムを制御します。

Instructions

まず、Select ジェスチャを検出できるよりもスクリプトを作成します。

  • Scripts フォルダー **、GazeGestureManager という名前のスクリプトを作成します**。
  • GazeGestureManager スクリプトを HierarchyOrigamiCollection オブジェクト にドラッグします。
  • 次のコード を追加して、Visual Studio GazeGestureManager スクリプトを開きます。
using UnityEngine;
using UnityEngine.XR.WSA.Input;

public class GazeGestureManager : MonoBehaviour
{
    public static GazeGestureManager Instance { get; private set; }

    // Represents the hologram that is currently being gazed at.
    public GameObject FocusedObject { get; private set; }

    GestureRecognizer recognizer;

    // Use this for initialization
    void Start()
    {
        Instance = this;

        // Set up a GestureRecognizer to detect Select gestures.
        recognizer = new GestureRecognizer();
        recognizer.Tapped += (args) =>
        {
            // Send an OnSelect message to the focused object and its ancestors.
            if (FocusedObject != null)
            {
                FocusedObject.SendMessageUpwards("OnSelect", SendMessageOptions.DontRequireReceiver);
            }
        };
        recognizer.StartCapturingGestures();
    }

    // Update is called once per frame
    void Update()
    {
        // Figure out which hologram is focused this frame.
        GameObject oldFocusObject = FocusedObject;

        // Do a raycast into the world based on the user's
        // head position and orientation.
        var headPosition = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;

        RaycastHit hitInfo;
        if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
        {
            // If the raycast hit a hologram, use that as the focused object.
            FocusedObject = hitInfo.collider.gameObject;
        }
        else
        {
            // If the raycast did not hit a hologram, clear the focused object.
            FocusedObject = null;
        }

        // If the focused object changed this frame,
        // start detecting fresh gestures again.
        if (FocusedObject != oldFocusObject)
        {
            recognizer.CancelGestures();
            recognizer.StartCapturingGestures();
        }
    }
}
  • Scripts フォルダーに、今回は SphereCommands という名前の別のスクリプトを作成します
  • 階層ビュー で OrigamiCollection オブジェクトを展開します。
  • SphereCommands スクリプトを [ 階層] パネル の Sphere1 オブジェクトにドラッグします。
  • SphereCommands スクリプトを [ 階層] パネル の Sphere2 オブジェクトにドラッグします。
  • スクリプトを編集用に Visual Studio開き、既定のコードを次のコードに置き換えます。
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    // Called by GazeGestureManager when the user performs a Select gesture
    void OnSelect()
    {
        // If the sphere has no Rigidbody component, add one to enable physics.
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = this.gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }
}
  • アプリをエクスポートし、ビルドし、HoloLensします。
  • シーンを見て回り、球の 1 つを中央に向けます。
  • Xbox コントローラー の [A] ボタンを押すか、Space キーを押して [選択] ジェスチャをシミュレートします。

第 4 章 - 音声

この章では、2 つの音声コマンド(ドロップされた球を元の場所に返す "世界のリセット" と、球を落とす "球のドロップ" の 2 つの音声コマンド) のサポートを追加します。

目標

  • 常にバックグラウンドでリッスンする音声コマンドを追加します。
  • 音声コマンドに反応するホログラムを作成します。

手順

  • Scripts フォルダー に、SpeechManager という名前のスクリプト を作成します
  • SpeechManager スクリプトを階層の OrigamiCollection オブジェクト にドラッグします
  • SpeechManager スクリプトを 開き、Visual Studio。
  • このコードをコピーして SpeechManager.cs に貼り付け 、すべて 保存します
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.Speech;

public class SpeechManager : MonoBehaviour
{
    KeywordRecognizer keywordRecognizer = null;
    Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();

    // Use this for initialization
    void Start()
    {
        keywords.Add("Reset world", () =>
        {
            // Call the OnReset method on every descendant object.
            this.BroadcastMessage("OnReset");
        });

        keywords.Add("Drop Sphere", () =>
        {
            var focusObject = GazeGestureManager.Instance.FocusedObject;
            if (focusObject != null)
            {
                // Call the OnDrop method on just the focused object.
                focusObject.SendMessage("OnDrop", SendMessageOptions.DontRequireReceiver);
            }
        });

        // Tell the KeywordRecognizer about our keywords.
        keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());

        // Register a callback for the KeywordRecognizer and start recognizing!
        keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
        keywordRecognizer.Start();
    }

    private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
    {
        System.Action keywordAction;
        if (keywords.TryGetValue(args.text, out keywordAction))
        {
            keywordAction.Invoke();
        }
    }
}
  • 次の コマンドで SphereCommands スクリプトをVisual Studio。
  • 次のようにスクリプトを更新します。
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    Vector3 originalPosition;

    // Use this for initialization
    void Start()
    {
        // Grab the original local position of the sphere when the app starts.
        originalPosition = this.transform.localPosition;
    }

    // Called by GazeGestureManager when the user performs a Select gesture
    void OnSelect()
    {
        // If the sphere has no Rigidbody component, add one to enable physics.
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = this.gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }

    // Called by SpeechManager when the user says the "Reset world" command
    void OnReset()
    {
        // If the sphere has a Rigidbody component, remove it to disable physics.
        var rigidbody = this.GetComponent<Rigidbody>();
        if (rigidbody != null)
        {
            rigidbody.isKinematic = true;
            Destroy(rigidbody);
        }

        // Put the sphere back into its original local position.
        this.transform.localPosition = originalPosition;
    }

    // Called by SpeechManager when the user says the "Drop sphere" command
    void OnDrop()
    {
        // Just do the same logic as a Select gesture.
        OnSelect();
    }
}
  • アプリをエクスポートし、ビルドし、HoloLensします。
  • エミュレーターは PC のマイクをサポートし、音声に応答します。カーソルが球の 1 つ上に表示され、"Drop Sphere" と表示されるビューを調整します。
  • "世界の リセット" と言って、最初の位置に戻ります。

第 5 章 - 空間サウンド

この章では、アプリに音楽を追加し、特定のアクションに対して効果音をトリガーします。 空間サウンドを使用して 、3D 空間内の特定の場所にサウンドを与えます。

目標

  • 世界でホログラムを聞く。

手順

  • Unity で、上部のメニューから [Edit > Project 設定 > Audio]を選択します
  • Spatializer プラグイン設定を見つけて**、MS HRTF Spatializer を選択します**。
  • [ホログラム から 、Hierarchy Panel の OrigamiCollection オブジェクトに 、オブジェクトを ドラッグします。
  • [OrigamiCollection] を選択 し、オーディオ ソース コンポーネントを探 します。 次のプロパティを変更します。
    • Spatialize プロパティを確認 します。
    • [Play On Awake] を確認します
    • スライダー を右に ドラッグして、Spatial Blend を 3D に変更します。
    • Loop プロパティ を確認 します。
    • [3D サウンド] 設定 展開し、[ Doppler Level ] に **「0.1」**と入力します
    • [ ボリューム ロールオフ] を [対数ロールオフ] に設定します
    • [ 最大距離] を 20 に設定します
  • Scripts フォルダー **、SphereSounds という名前のスクリプトを作成します**。
  • SphereSounds を 階層内の Sphere1 オブジェクトと Sphere2 オブジェクト にドラッグします。
  • のコードをVisual Studio SphereSounds を開き、次のコードを更新して [すべて保存]を選択します
using UnityEngine;

public class SphereSounds : MonoBehaviour
{
    AudioSource impactAudioSource = null;
    AudioSource rollingAudioSource = null;

    bool rolling = false;

    void Start()
    {
        // Add an AudioSource component and set up some defaults
        impactAudioSource = gameObject.AddComponent<AudioSource>();
        impactAudioSource.playOnAwake = false;
        impactAudioSource.spatialize = true;
        impactAudioSource.spatialBlend = 1.0f;
        impactAudioSource.dopplerLevel = 0.0f;
        impactAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        impactAudioSource.maxDistance = 20f;

        rollingAudioSource = gameObject.AddComponent<AudioSource>();
        rollingAudioSource.playOnAwake = false;
        rollingAudioSource.spatialize = true;
        rollingAudioSource.spatialBlend = 1.0f;
        rollingAudioSource.dopplerLevel = 0.0f;
        rollingAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        rollingAudioSource.maxDistance = 20f;
        rollingAudioSource.loop = true;

        // Load the Sphere sounds from the Resources folder
        impactAudioSource.clip = Resources.Load<AudioClip>("Impact");
        rollingAudioSource.clip = Resources.Load<AudioClip>("Rolling");
    }

    // Occurs when this object starts colliding with another object
    void OnCollisionEnter(Collision collision)
    {
        // Play an impact sound if the sphere impacts strongly enough.
        if (collision.relativeVelocity.magnitude >= 0.1f)
        {
            impactAudioSource.Play();
        }
    }

    // Occurs each frame that this object continues to collide with another object
    void OnCollisionStay(Collision collision)
    {
        Rigidbody rigid = gameObject.GetComponent<Rigidbody>();

        // Play a rolling sound if the sphere is rolling fast enough.
        if (!rolling && rigid.velocity.magnitude >= 0.01f)
        {
            rolling = true;
            rollingAudioSource.Play();
        }
        // Stop the rolling sound if rolling slows down.
        else if (rolling && rigid.velocity.magnitude < 0.01f)
        {
            rolling = false;
            rollingAudioSource.Stop();
        }
    }

    // Occurs when this object stops colliding with another object
    void OnCollisionExit(Collision collision)
    {
        // Stop the rolling sound if the object falls off and stops colliding.
        if (rolling)
        {
            rolling = false;
            impactAudioSource.Stop();
            rollingAudioSource.Stop();
        }
    }
}
  • スクリプトを保存し、Unity に戻します。
  • アプリをエクスポートし、ビルドし、HoloLensします。
  • 完全な効果を得る場合は、ヘッドセットを装着し、ステージからさらに近くに移動して、音の変化を聞き取ります。

第 6 章 - 空間マッピング

次に、空間マッピングを 使用 して、ゲーム ボードを現実の世界の実際のオブジェクトに配置します。

目標

  • 現実世界を仮想世界に取り込む。
  • ホログラムを最も重要な場所に配置します。

Instructions

  • ウィンドウの [ホログラム] フォルダーをProjectします。
  • 空間マッピング 資産を階層 のルートにドラッグ します
  • 階層内の 空間マッピング オブジェクトをクリックします。
  • [インスペクタ ー] パネルで、 次のプロパティを変更します。
    • [ビジュアル メッシュ の描画] ボックスをオン にします。
    • [ 描画素材] を 見つけて、右側の円をクリックします。 上部の 検索フィールドに「wireframe」 と入力します。 結果をクリックし、ウィンドウを閉じます。
  • アプリをエクスポートし、ビルドし、HoloLensします。
  • アプリが実行されると、以前にスキャンされた実際の生活室のメッシュがワイヤーフレームにレンダリングされます。
  • ローリング球がステージから降り、床に落ちているのを見てみよう。

次に、OrigamiCollection を新しい場所に移動する方法について説明します。

  • Scripts フォルダー **、TapToPlaceParent という名前のスクリプトを作成します**。
  • [階層 ] で OrigamiCollection を展開し、Stage オブジェクト を選択 します。
  • TapToPlaceParent スクリプトを Stage オブジェクトにドラッグします。
  • 次の 手順で TapToPlaceParent スクリプトをVisual Studio、次の手順に従って更新します。
using UnityEngine;

public class TapToPlaceParent : MonoBehaviour
{
    bool placing = false;

    // Called by GazeGestureManager when the user performs a Select gesture
    void OnSelect()
    {
        // On each Select gesture, toggle whether the user is in placing mode.
        placing = !placing;

        // If the user is in placing mode, display the spatial mapping mesh.
        if (placing)
        {
            SpatialMapping.Instance.DrawVisualMeshes = true;
        }
        // If the user is not in placing mode, hide the spatial mapping mesh.
        else
        {
            SpatialMapping.Instance.DrawVisualMeshes = false;
        }
    }

    // Update is called once per frame
    void Update()
    {
        // If the user is in placing mode,
        // update the placement to match the user's gaze.

        if (placing)
        {
            // Do a raycast into the world that will only hit the Spatial Mapping mesh.
            var headPosition = Camera.main.transform.position;
            var gazeDirection = Camera.main.transform.forward;

            RaycastHit hitInfo;
            if (Physics.Raycast(headPosition, gazeDirection, out hitInfo,
                30.0f, SpatialMapping.PhysicsRaycastMask))
            {
                // Move this object's parent object to
                // where the raycast hit the Spatial Mapping mesh.
                this.transform.parent.position = hitInfo.point;

                // Rotate this object's parent object to face the user.
                Quaternion toQuat = Camera.main.transform.localRotation;
                toQuat.x = 0;
                toQuat.z = 0;
                this.transform.parent.rotation = toQuat;
            }
        }
    }
}
  • アプリをエクスポート、ビルド、デプロイします。
  • これで、選択ジェスチャ (A または Spacebar) を使用してゲームを特定の場所に配置し、次に新しい場所に移動し、[選択] ジェスチャを再度使用して、ゲームを特定の場所に配置できます。

最後です

これで、このチュートリアルは終了です。

学習した内容は次のとおりです。

  • Unity でホログラフィック アプリを作成する方法。
  • 視線入力、ジェスチャ、音声、サウンド、空間マッピングを利用する方法。
  • アプリをビルドしてデプロイする方法については、Visual Studio。

これで、独自のホログラフィック アプリの作成を開始する準備ができました。

こちらもご覧ください