HoloLens (första generationen) Basics 101: Slutför projektet med enheten


Viktigt

Självstudierna Mixed Reality Academy har utformats med HoloLens (1:a generationen), Unity 2017 och Mixed Reality Immersive Headsets i åtanke. Därför anser vi att det är viktigt att lämna de här självstudierna på plats för utvecklare som fortfarande letar efter vägledning i utvecklingen för dessa enheter. De här självstudierna uppdateras inte med de senaste verktygen eller interaktionerna som används för HoloLens 2 och kanske inte är kompatibla med nyare versioner av Unity. De kommer att finnas kvar för att fortsätta arbeta med de enheter som stöds. En ny serie självstudier har publicerats för HoloLens 2.


Den här självstudien vägled dig genom ett komplett projekt, inbyggt i Unity, som visar grundläggande Windows Mixed Reality-funktioner på HoloLens inklusive blick, gester, röstindata, rumsligt ljud och rumslig mappning.

Självstudien tar cirka 1 timme att slutföra.

Stöd för enheter

Kurs HoloLens Integrerande headset
MR Basics 101: Slutför projektet med enheten ✔️

Innan du börjar

Förutsättningar

Project filer

  • Ladda ned de filer som krävs av projektet. Kräver Unity 2017.2 eller senare.
    • Om du fortfarande behöver unity 5.6-stöd kan du använda den här versionen.
    • Om du fortfarande behöver unity 5.5-stöd kan du använda den här versionen.
    • Om du fortfarande behöver unity 5.4-stöd kan du använda den här versionen.
  • Ta bort arkivering av filerna till skrivbordet eller någon annan plats som är lätt att nå. Behåll mappnamnet som Förnamn.

Anteckning

Om du vill titta igenom källkoden innan du laddar ned den finns den på GitHub.

Kapitel 1 – "Holo"-världen

I det här kapitlet ska vi konfigurera vårt första Unity-projekt och gå igenom bygg- och distributionsprocessen.

Mål

  • Konfigurera Unity för holografisk utveckling.
  • Skapa ett hologram.
  • Se ett hologram som du har gjort.

Instruktioner

  • Starta Unity.
  • Välj Öppna.
  • Ange plats som mappen Mapp som du tidigare avarkiverade.
  • Välj Alternativet och klicka på Välj mapp.
  • Eftersom Project Project inte innehåller en scen sparar du den tomma standardscenen till en ny fil med: FileSave / Scene As.
  • Ge den nya scenen ett namn och tryck på knappen Spara.

Konfigurera den virtuella huvudkameran

  • I hierarkipanelen väljer du Huvudkamera.
  • I Kontroll anger du dess transformeringsposition till 0,0,0.
  • Leta reda på egenskapen Clear Flags och ändra listrutan från Skybox tillSolid color (Heldragen färg).
  • Klicka på fältet Bakgrund för att öppna en färgväljare.
  • Ange R, G, B och A till 0.

Konfigurera scenen

  • I hierarkipanelen klickar du på Skapa ochskapa tom.
  • Högerklicka på det nya GameObject och välj Byt namn. Byt namn på GameObject tillMappCollection.
  • Från mappen Hologram på Project panelen (expandera Tillgångar och välj Hologram eller dubbelklicka på mappen Hologram på Project panelen):
    • Dra Stage (Fas) till hierarkin för att vara underordnad Tillval.
    • Dra Sphere1 till hierarkin för att vara underordnad Tillval.
    • Dra Sphere2 till hierarkin för att vara underordnad Tillval.
  • Högerklicka på objektet Riktningsbelysninghierarkipanelen och välj Ta bort.
  • Dra Lights Hologram roten på hierarkipanelen från mappen .
  • I hierarkin väljer du Alternativet.
  • I Kontroll anger du transformeringspositionen till 0, -0,5, 2.0.
  • Tryck på knappen Spela upp i Unity för att förhandsgranska dina hologram.
  • Du bör se Objekt objekt i förhandsgranskningsfönstret.
  • Tryck på Spela upp en andra gång för att stoppa förhandsgranskningsläget.

Exportera projektet från Unity till Visual Studio

  • I Unity väljer du Inställningar>.

  • Välj Universell Windows-plattform i listan Plattform och klicka på Växla plattform.

  • Ange SDK till Universal 10 ochBuild Type (Versionstyp ) till D3D.

  • Kontrollera Unity C#-projekt.

  • Klicka på Lägg till öppna scener för att lägga till scenen.

  • Klicka på Skapa.

  • I utforskarfönstret som visas skapar du en Ny mapp med namnet "App".

  • Klicka på appmappen.

  • Tryck på Välj mapp.

  • När Unity är klart Utforskaren ett fönster.

  • Öppna mappen App.

  • Öppna (dubbelklicka på) En.sln.

  • Använd det översta verktygsfältet i Visual Studio ändra målet från Felsök till Version och från ARM till X86.

  • Klicka på pilen bredvid knappen Enhet och välj Fjärrdator att distribuera via Wi-Fi.

    • Ange Adress till namnet eller IP-adressen för din HoloLens. Om du inte känner till enhetens IP-adress kan du titta i avancerade alternativ för Inställningar > Network & Internet > eller fråga Cortana "Hej Cortana, Vad är min IP-adress?"
    • Om enheten HoloLens via USB kan du i stället välja Enhet att distribuera via USB.
    • Lämna Autentiseringsläge inställtUniversell.
    • Klicka på Välj
  • Klicka på Felsök > Start utan felsökning eller tryckCtrl + F5. Om det här är första gången du distribuerar till din enhet måste du koppla ihop den med Visual Studio.

  • Nu kommer Projekt att byggas, distribueras till HoloLens och sedan köras.

  • Sätt på din HoloLens och titta runt för att se dina nya hologram.

Kapitel 2 – Blick

I det här kapitlet introducerar vi det första av tre sätt att interagera med dina hologram – blick.

Mål

  • Visualisera din blick med en världslåst markör.

Instruktioner

  • Gå tillbaka till ditt Unity-projekt och stäng fönstret Skapa Inställningar om det fortfarande är öppet.
  • Välj mappen HologramProject panelen.
  • Dra markörobjektet till panelen Hierarki på rotnivå.
  • Dubbelklicka på markörobjektet för att ta en närmare titt på det.
  • Högerklicka på mappen Skript i Project panelen.
  • Klicka på menyn Skapa undermeny.
  • Välj C#-skript.
  • Ge skriptet namnet WorldCursor. Obs! Namnet är case-sensitive. Du behöver inte lägga till .cs-tillägget.
  • Välj markörobjektet på panelen Hierarki.
  • Dra och släpp WorldCursor-skriptet i kontrollpanelen.
  • Dubbelklicka på WorldCursor-skriptet för att öppna det i Visual Studio.
  • Kopiera och klistra in den här koden i WorldCursor.cs och Spara alla.
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 the cursor 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;
        }
    }
}
  • Återskapa appen från File > Build Inställningar.
  • Gå tillbaka till Visual Studio som tidigare användes för att distribuera till HoloLens.
  • Välj Läs in alla på nytt när du uppmanas att göra det.
  • Klicka på Felsök –> Starta utan felsökning eller tryck på Ctrl + F5.
  • Titta nu runt i scenen och lägg märke till hur markören interagerar med formen på objekt.

Kapitel 3 – Gester

I det här kapitlet lägger vi till stöd för gester. När användaren väljer en papperssfär gör vi att sfären faller genom att aktivera tyngdkraften med hjälp av Unitys fysikmotor.

Mål

  • Kontrollera hologrammen med gesten Välj.

Instruktioner

Vi börjar med att skapa ett skript och sedan kan identifiera gesten Välj.

  • I mappen Skript skapar du ett skript med namnet GazeGestureManager.
  • Dra skriptet GazeGestureManager till objektet ScriptCollection i hierarkin.
  • Öppna skriptet GazeGestureManager i Visual Studio lägg till följande kod:
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 Awake()
    {
        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();
        }
    }
}
  • Skapa ett annat skript i mappen Skript, den här gången med namnet SphereCommands.
  • Expandera Objektet GrupprincipCollection i vyn Hierarki.
  • Dra skriptet SphereCommands till Sphere1-objektet på panelen Hierarki.
  • Dra skriptet SphereCommands till Sphere2-objektet på panelen Hierarki.
  • Öppna skriptet i Visual Studio för redigering och ersätt standardkoden med följande:
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;
        }
    }
}
  • Exportera, skapa och distribuera appen till din HoloLens.
  • Titta på en av sfärerna.
  • Utför select-gesten och se sfären släppas på ytan nedanför.

Kapitel 4 – Röst

I det här kapitlet lägger vi till stöd för två röstkommandon : "Reset world" för att returnera de bortrullningade sfärerna till deras ursprungliga plats och "Drop sphere" för att få sfären att faller.

Mål

  • Lägg till röstkommandon som alltid lyssnar i bakgrunden.
  • Skapa ett hologram som reagerar på ett röstkommando.

Instruktioner

  • Skapa ett skript med namnet SpeechManager i mappen Skript.
  • Dra SpeechManager-skriptet till Objektcollection-objektet i hierarkin
  • Öppna SpeechManager-skriptet i Visual Studio.
  • Kopiera och klistra in den här koden i SpeechManager.cs och Spara alla:
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();
        }
    }
}
  • Öppna SphereCommands-skriptet i Visual Studio.
  • Uppdatera skriptet så att det ser ut så här:
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();
    }
}
  • Exportera, skapa och distribuera appen till din HoloLens.
  • Titta på en av sfärerna och säg "Drop Sphere".
  • Säg "Återställ världen" för att ta dem tillbaka till sina ursprungliga positioner.

Kapitel 5 – Rumsligt ljud

I det här kapitlet lägger vi till musik i appen och utlöser sedan ljudeffekter på vissa åtgärder. Vi kommer att använda rumsligt ljud för att ge ljud en specifik plats i 3D-utrymme.

Mål

  • Hör hologram i din värld.

Instruktioner

  • I Unity väljer du på den översta menyn Redigera > Project Inställningar > Ljud
  • På panelen Inspector (Kontroll) på höger sida hittar du inställningen Spatializer Plugin (Plugin-program för spatializer ) och väljer MS HRTF Spatializer.
  • Från mappen Hologram i Project-panelen drar du objektet Jäser till Objektet Harcollection i hierarkipanelen.
  • VäljKorrigeringCollection och leta reda på komponenten Ljudkälla i kontrollpanelen. Ändra dessa egenskaper:
    • Kontrollera egenskapen Spatialize .
    • Kontrollera Spela upp vid uppvaknande.
    • Ändra Spatial Blend till 3D genom att dra skjutreglaget hela vägen till höger. Värdet bör ändras från 0 till 1 när du flyttar skjutreglaget.
    • Kontrollera Loop.
    • Expandera 3D Sound Inställningar och ange 0.1 för Nivån Fördr.
    • Ange Volume Rolloff tillLogarithmic Rolloff.
    • Ange Maxavstånd till 20.
  • I mappen Skript skapar du ett skript med namnet Sphere Sphere Spheres.
  • Dra och släpp SphereLots till objekten Sphere1och Sphere2 i hierarkin.
  • Open SphereUndan Visual Studio, uppdatera följande kod och Spara alla.
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();
        }
    }
}
  • Spara skriptet och återgå till Unity.
  • Exportera, skapa och distribuera appen till din HoloLens.
  • Gå närmare och längre från fasen och gå sida-till-sida för att höra ljuden ändras.

Kapitel 6 – Rumslig mappning

Nu ska vi använda rumslig mappning för att placera spelplanen på ett verkligt objekt i den verkliga världen.

Mål

  • Ta din verkliga värld till den virtuella världen.
  • Placera dina hologram där de är viktigast för dig.

Instruktioner

  • I Unity klickar du på Hologram i Project panelen.
  • Dra tillgången Spatial Mapping (Rumslig mappning) till roten i hierarkin.
  • Klicka på objektet Spatial Mapping i hierarkin.
  • Ändra följande egenskaper på panelen Kontroll:
    • Markera rutan Rita visuella nät .
    • Leta upp Draw Material (Rita material) och klicka på cirkeln till höger. Skriv "wireframe" i sökfältet längst upp. Klicka på resultatet och stäng sedan fönstret. När du gör detta ska värdet för Draw Material anges till Wireframe.
  • Exportera, skapa och distribuera appen till din HoloLens.
  • När appen körs överlappar ett wireframe-nät din verkliga värld.
  • Se hur en rullande sfär faller från scenen och på marken!

Nu ska vi visa dig hur du flyttarKode-instruktionen till en ny plats:

  • I mappen Skript skapar du ett skript med namnet TapToPlaceParent.
  • I hierarkin expanderar du Instruktionsavsnittet och väljer objektet Stage ( Stadium).
  • Dra skriptet TapToPlaceParent till objektet Stage.
  • Öppna skriptet TapToPlaceParent i Visual Studio och uppdatera det till följande:
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;
            }
        }
    }
}
  • Exportera, skapa och distribuera appen.
  • Nu bör du kunna placera spelet på en viss plats genom att titta på den, använda gesten Välj och sedan flytta till en ny plats och använda gesten Välj igen.

Kapitel 7 – Holographic fun

Mål

  • Visa ingångarna till en holografisk undervärld.

Instruktioner

Nu ska vi visa dig hur du hittar den holografiska undervärlden:

  • Från Hologram på Project panelen:
    • Dra Underworld till hierarkin för att vara underordnad Tillval.
  • I mappen Skript skapar du ett skript med namnet HitTarget.
  • I hierarkin expanderar du Instruktionsavsnittet.
  • Expandera objektet Fas och välj målobjektet (blå fläkt).
  • Dra Skriptet HitTarget till målobjektet .
  • Öppna Skriptet HitTarget i Visual Studio och uppdatera det till följande:
using UnityEngine;

public class HitTarget : MonoBehaviour
{
    // These public fields become settable properties in the Unity editor.
    public GameObject underworld;
    public GameObject objectToHide;

    // Occurs when this object starts colliding with another object
    void OnCollisionEnter(Collision collision)
    {
        // Hide the stage and show the underworld.
        objectToHide.SetActive(false);
        underworld.SetActive(true);

        // Disable Spatial Mapping to let the spheres enter the underworld.
        SpatialMapping.Instance.MappingEnabled = false;
    }
}
  • I Unity väljer du objektet Mål.
  • Två offentliga egenskaper visas nu på komponenten Träffmål och behöver referera till objekt i vår scen:
    • Dra Underworld från panelen Hierarki till egenskapen Underworldkomponenten Träffmål .
    • Dra Fas från panelen Hierarki till egenskapen Objekt att dölja på komponenten Träffmål .
  • Exportera, skapa och distribuera appen.
  • Placera Samlingen Collection på ordet och använd sedan gesten Välj för att göra en sfärs släppning.
  • När sfären når målet (blå fläkt) sker en explosion. Samlingen döljs och ett hål i undervärlden visas.

Slutet

Och det är slutet på den här självstudien!

Du har lärt dig att:

  • Så här skapar du en holografisk app i Unity.
  • Hur du använder blick, gest, röst, ljud och rumslig mappning.
  • Skapa och distribuera en app med hjälp av Visual Studio.

Nu är du redo att börja skapa en egen holografisk upplevelse!

Se även