HoloLens (1:a gen) Input 211: Gesture

Viktigt

Självstudierna Mixed Reality Academy har utformats med HoloLens (1:a gen), 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.

Gester omvandlar användarens avsikt till handling. Med gester kan användarna interagera med hologram. I den här kursen lär vi dig att spåra användarens händer, svara på användarindata och ge feedback till användaren baserat på handtillstånd och plats.

I MR Basics 101använde vi en enkel air-tap-gest för att interagera med våra hologram. Nu ska vi gå längre än "air-tap"-gesten och utforska nya begrepp för att:

  • Identifiera när användarens hand spåras och ge feedback till användaren.
  • Använd en navigeringsgest för att rotera våra hologram.
  • Ge feedback när användarens hand är på väg att gå ut ur vyn.
  • Använd manipuleringshändelser så att användarna kan flytta hologram med händerna.

I den här kursen går vi tillbaka till Unity-projektet Model Explorer, som vi skapade i MR Input 210. Astronauten är tillbaka för att hjälpa oss att utforska de här nya gestbegreppen.

Viktigt

Videorna som bäddades in i vart och ett av kapitlen nedan registrerades med en äldre version av Unity och Mixed Reality Toolkit. De stegvisa anvisningarna är korrekta och aktuella, men du kan se skript och visuella objekt i motsvarande videor som är in datera. Videorna finns kvar för eftervärlden och eftersom de begrepp som tas upp fortfarande gäller.

Stöd för enheter

Kurs HoloLens Integrerande headset
MR Input 211: Gesture ✔️ ✔️

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.
  • Ta bort arkivering av filerna till skrivbordet eller någon annan plats som är lätt att nå.

Anteckning

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

Errata och anteckningar

  • "Aktivera Just My Code" måste inaktiveras ( avmarkerat ) i Visual Studio under Verktyg->Options->Debugging för att komma till brytpunkter i koden.

Kapitel 0 – Unity-konfiguration

Instruktioner

  1. Starta Unity.
  2. Välj Öppna.
  3. Navigera till gestermappen som du tidigare avarkiverade.
  4. Leta upp och välj mappen Starting Model Explorer / (Starta modellutforskaren).
  5. Klicka på knappen Välj mapp.
  6. I Project panelen expanderar du mappen Scenes.
  7. Dubbelklicka på ModelExplorer-scenen för att läsa in den i Unity.

Byggnad

  1. I Unity väljer du File > Build Inställningar.
  2. Om Scenes/ModelExplorer inte visas i Scenes In Build klickar du på Lägg till öppna scener för att lägga till scenen.
  3. Om du utvecklar specifikt för HoloLens anger du Målenhet till HoloLens. Annars lämnar du den på Valfri enhet.
  4. Kontrollera att Versionstyp är inställt på D3D och ATT SDK är inställt på Senaste installerade (som ska vara SDK 16299 eller nyare).
  5. Klicka på Skapa.
  6. Skapa en ny mapp med namnet "App".
  7. Klicka på mappen App.
  8. Tryck på Välj mapp så börjar Unity skapa projektet för Visual Studio.

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

  1. Öppna mappen App.
  2. Öppna ModelExplorer-Visual Studio lösningen.

Om du distribuerar till HoloLens:

  1. Använd det översta verktygsfältet i Visual Studio ändra målet från Felsök till Version och från ARM till x86.
  2. Klicka på listrpilen bredvid knappen Lokal dator och välj Fjärrdator.
  3. Ange din HoloLens IP-adress och ange Autentiseringsläge till Universellt (okrypterat protokoll). Klicka på Välj. Om du inte känner till enhetens IP-adress kan du titta i Inställningar > Network & Internet > Advanced Options (Avancerade alternativ för Internet).
  4. I den översta menyraden klickar du på Debug -> Start Without debugging (Felsök – starta utan felsökning) eller tryck på Ctrl + F5. Om det här är första gången du distribuerar till din enhet måste du koppla det till Visual Studio.
  5. När appen har distribuerats stänger du Fitbox med en select-gest.

Om du distribuerar till ett integrerande headset:

  1. Använd det översta verktygsfältet i Visual Studio ändra målet från Felsök till Version och från ARM till x64.
  2. Kontrollera att distributionsmålet är inställt på Lokal dator.
  3. I den översta menyraden klickar du på Debug -> Start Without debugging (Felsök – starta utan felsökning) eller tryck på Ctrl + F5.
  4. När appen har distribuerats stänger du Fitbox genom att hämta utlösaren på en rörelsekontroll.

Anteckning

Du kanske ser några röda fel Visual Studio panelen Fel. Det är säkert att ignorera dem. Växla till panelen Utdata för att visa faktiska byggförloppet. Fel i panelen Utdata kräver att du gör en korrigering (oftast orsakas de av ett misstag i ett skript).

Kapitel 1 – Hand upptäckt feedback

Mål

  • Prenumerera på handspårningshändelser.
  • Använd markörfeedback för att visa användare när en hand spåras.

Anteckning

På HoloLens 2 har händer identifierats som bränder när händerna är synliga (inte bara när ett finger pekar uppåt).

Instruktioner

  • Expandera InputManager-objektet i hierarkipanelen.
  • Leta upp och välj objektet GesturesInput.

Skriptet InteractionInputSource.cs utför följande steg:

  1. Prenumererar på händelserna InteractionSourceDetected och InteractionSourceLost.
  2. Anger HandDetected-tillståndet.
  3. Avbryter prenumerationen på händelserna InteractionSourceDetected och InteractionSourceLost.

Nu ska vi uppgradera markören från MR Input 210 till en som visar feedback beroende på användarens åtgärder.

  1. I panelen Hierarki väljer du objektet Markör och tar bort det.
  2. I panelen Project du efter CursorWithFeedback och drar den till panelen Hierarki.
  3. Klicka på InputManager på panelen Hierarki och dra sedan objektet CursorWithFeedback från hierarkin till InputManagers SimpleSinglePointerSelector-fält Markör längst ned i Kontroll.
  4. Klicka på CursorWithFeedback i hierarkin.
  5. I panelen Kontroll expanderar du Markörtillståndsdata i skriptet Objektmarkör.

Markörens tillståndsdata fungerar så här:

  • Observera-tillstånd innebär att ingen hand identifieras och att användaren bara tittar runt.
  • Alla interaktionstillstånd innebär att en hand eller kontrollant identifieras.
  • Ett hovringstillstånd innebär att användaren tittar på ett hologram.

Skapa och distribuera

  • I Unity använder du File > Build Inställningar för att återskapa programmet.
  • Öppna mappen App.
  • Om den inte redan är öppen öppnar du ModelExplorer Visual Studio Solution .
    • (Om du redan har skapat/distribuerat det här projektet i Visual Studio under set-up, kan du öppna den instansen av VS och klicka på Läs in alla på nytt när du uppmanas till det).
  • I Visual Studio klickar du på Debug -> Start Without debugging (Felsök - starta utan felsökning) eller trycker på Ctrl + F5.
  • När programmet har distribuerats till HoloLens stänger du fitbox med hjälp av air-tap-gesten.
  • Flytta din hand till vyn och peka ditt index finger mot luften för att starta handspårningen.
  • Flytta din hand åt vänster, höger, uppåt och nedåt.
  • Se hur markören ändras när din hand identifieras och sedan försvinner från vyn.
  • Om du använder ett integrerande headset måste du ansluta och koppla från styrenheten. Den här feedbacken blir mindre intressant på en integrerande enhet eftersom en ansluten styrenhet alltid kommer att vara "tillgänglig".

Kapitel 2 – Navigering

Mål

  • Använd navigeringsgesthändelser för att rotera astronauten.

Instruktioner

För att använda navigeringsgester i appen ska vi redigera GestureAction.cs för att rotera objekt när gesten Navigering inträffar. Dessutom lägger vi till feedback till markören för att visa när Navigering är tillgängligt.

  1. I panelen Hierarki expanderar du CursorWithFeedback.
  2. Leta upp Hologram ScrollFeedback i mappen .
  3. Dra och släpp prefab-förfabriken ScrollFeedback till CursorWithFeedback GameObject i hierarkin.
  4. Klicka på CursorWithFeedback.
  5. I panelen Kontroll klickar du på knappen Lägg till komponent.
  6. I menyn skriver du i sökrutan CursorFeedback. Välj sökresultatet.
  7. Dra och släpp objektet ScrollFeedback från hierarkin till egenskapen Scroll Detected Game Object i komponenten Markörfeedback i Inspector.
  8. På panelen Hierarki väljer du Objektet Förman.
  9. I panelen Kontroll klickar du på knappen Lägg till komponent.
  10. I menyn skriver du i sökrutan Geståtgärd. Välj sökresultatet.

Öppna sedan GestureAction.cs i Visual Studio. I kodningsövningen 2.c redigerar du skriptet för att göra följande:

  1. Rotera ObjektMan-objektet när en navigeringsgest utförs.
  2. Beräkna rotationFactor för att styra mängden rotation som tillämpas på objektet.
  3. Rotera objektet runt y-axeln när användaren flyttar sin hand åt vänster eller höger.

Slutför kodningsövningarna 2.c i skriptet eller ersätt koden med den färdiga lösningen nedan:

using HoloToolkit.Unity.InputModule;
using UnityEngine;

/// <summary>
/// GestureAction performs custom actions based on
/// which gesture is being performed.
/// </summary>
public class GestureAction : MonoBehaviour, INavigationHandler, IManipulationHandler, ISpeechHandler
{
    [Tooltip("Rotation max speed controls amount of rotation.")]
    [SerializeField]
    private float RotationSensitivity = 10.0f;

    private bool isNavigationEnabled = true;
    public bool IsNavigationEnabled
    {
        get { return isNavigationEnabled; }
        set { isNavigationEnabled = value; }
    }

    private Vector3 manipulationOriginalPosition = Vector3.zero;

    void INavigationHandler.OnNavigationStarted(NavigationEventData eventData)
    {
        InputManager.Instance.PushModalInputHandler(gameObject);
    }

    void INavigationHandler.OnNavigationUpdated(NavigationEventData eventData)
    {
        if (isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 2.c */

            // 2.c: Calculate a float rotationFactor based on eventData's NormalizedOffset.x multiplied by RotationSensitivity.
            // This will help control the amount of rotation.
            float rotationFactor = eventData.NormalizedOffset.x * RotationSensitivity;

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

    void INavigationHandler.OnNavigationCompleted(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void INavigationHandler.OnNavigationCanceled(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationStarted(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            InputManager.Instance.PushModalInputHandler(gameObject);

            manipulationOriginalPosition = transform.position;
        }
    }

    void IManipulationHandler.OnManipulationUpdated(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 4.a */

            // 4.a: Make this transform's position be the manipulationOriginalPosition + eventData.CumulativeDelta
        }
    }

    void IManipulationHandler.OnManipulationCompleted(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationCanceled(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void ISpeechHandler.OnSpeechKeywordRecognized(SpeechEventData eventData)
    {
        if (eventData.RecognizedText.Equals("Move Astronaut"))
        {
            isNavigationEnabled = false;
        }
        else if (eventData.RecognizedText.Equals("Rotate Astronaut"))
        {
            isNavigationEnabled = true;
        }
        else
        {
            return;
        }

        eventData.Use();
    }
}

Du ser att de andra navigeringshändelserna redan är ifyllda med viss information. Vi push-pushar GameObject till Toolkits InputSystems modala stack, så användaren behöver inte behålla fokus på astronauten när rotationen har påbörjats. På motsvarande sätt tar vi GameObject från stacken när gesten har slutförts.

Skapa och distribuera

  1. Återskapa programmet i Unity och skapa och distribuera sedan från Visual Studio för att köra det i HoloLens.
  2. Titta på astronauten. Två pilar ska visas på båda sidor av markören. Det här nya visuella objektet anger att astronauten kan roteras.
  3. Placera din hand i den färdiga positionen (indexfingret pekade mot HoloLens så att HoloLens börjar spåra din hand.
  4. Om du vill rotera astronauten sänker du indexfingret till en dra ihop-position och flyttar sedan din hand åt vänster eller höger för att utlösa NavigationX-gesten.

Kapitel 3 – Handvägledning

Mål

  • Använd handvägledningspoäng för att förutsäga när handspårningen kommer att gå förlorad.
  • Ge feedback på markören för att visa när användarens hand närmar sig kamerans kant.

Instruktioner

  1. På panelen Hierarki väljer du objektet CursorWithFeedback.
  2. I panelen Kontroll klickar du på knappen Lägg till komponent.
  3. I menyn skriver du i sökrutan Hand guidance (Vägledning för hand). Välj sökresultatet.
  4. Leta reda Project HandGuidanceFeedback i mappen Hologram panelen.
  5. Dra och släpp tillgången HandGuidanceFeedback till egenskapen Hand Guidance Indicator på panelen Inspector.

Skapa och distribuera

  • Återskapa programmet i Unity och skapa och distribuera sedan från Visual Studio för att uppleva appen på HoloLens.
  • Visa din hand och höj ditt indexfingr för att spåra det.
  • Börja rotera astronauten med navigeringsgesten (dra ihop ditt index och din tum).
  • Flytta din hand längst till vänster, höger, upp och ned.
  • När din hand närmar sig kanten av gesterramen bör en pil visas bredvid markören för att varna dig om att handspårningen kommer att gå förlorad. Pilen anger i vilken riktning du ska flytta din hand för att förhindra att spårning går förlorad.

Kapitel 4 – Manipulering

Mål

  • Använd manipulationshändelser för att flytta astronauten med händerna.
  • Ge feedback om markören så att användaren får veta när manipulering kan användas.

Instruktioner

Med GestureManager.cs och AstronautManager.cs kan vi göra följande:

  1. Använd nyckelordet "Flytta astronaut" för att aktivera manipulationsgester och " Rotera astronaut" för att inaktivera dem.
  2. Växla till att svara på Manipulation Gesture Recognizer.

Nu sätter vi igång.

  1. Skapa ett nytt tomt GameObject på panelen Hierarki. Ge den namnet AstronautManager.
  2. I panelen Kontroll klickar du på knappen Lägg till komponent.
  3. I menyn skriver du i sökrutan Astronaut Manager. Välj sökresultatet.
  4. I panelen Kontroll klickar du på knappen Lägg till komponent.
  5. I menyn skriver du i sökrutan Speech Input Source. Välj sökresultatet.

Nu ska vi lägga till de talkommandon som krävs för att styra astronautens interaktionstillstånd.

  1. Expandera avsnittet Nyckelord i Kontroll.
  2. Klicka på + till höger för att lägga till ett nytt nyckelord.
  3. Ange nyckelordet som Move Astronaut. Lägg gärna till en nyckelgenväg om du vill.
  4. Klicka på + till höger för att lägga till ett nytt nyckelord.
  5. Skriv Keyword (Nyckelord) som Rotate Astronaut (Rotera astronaut). Lägg gärna till en nyckelgenväg om du vill.
  6. Motsvarande hanterarkod finns i GestureAction.cs i hanteraren ISpeechHandler.OnSpewordWordRecognized.

Så här ställer du in speech input-källan för kapitel 4

Nu ska vi konfigurera feedback om manipulering för markören.

  1. Leta upp Project Feedback Hologram mappen i den nya panelen.
  2. Dra och släpp prefab-objektet PathingFeedback till objektet CursorWithFeedback i hierarkin.
  3. I panelen Hierarki klickar du på CursorWithFeedback.
  4. Dra och släpp pathingFeedback-objektet från hierarkin till egenskapen Pathing Detected Game Object i komponenten Markörfeedback i Inspector.

Nu måste vi lägga till kod i GestureAction.cs för att aktivera följande:

  1. Lägg till kod i funktionen IManipulationHandler.OnManipulationUpdated, som flyttar astronauten när en manipulationsgest identifieras.
  2. Beräkna rörelsevektorn för att avgöra var astronauten ska flyttas till baserat på handpositionen.
  3. Flytta astronauten till den nya positionen.

Slutför kodningsövningen 4.a i GestureAction.cs eller använd vår färdiga lösning nedan:

using HoloToolkit.Unity.InputModule;
using UnityEngine;

/// <summary>
/// GestureAction performs custom actions based on
/// which gesture is being performed.
/// </summary>
public class GestureAction : MonoBehaviour, INavigationHandler, IManipulationHandler, ISpeechHandler
{
    [Tooltip("Rotation max speed controls amount of rotation.")]
    [SerializeField]
    private float RotationSensitivity = 10.0f;

    private bool isNavigationEnabled = true;
    public bool IsNavigationEnabled
    {
        get { return isNavigationEnabled; }
        set { isNavigationEnabled = value; }
    }

    private Vector3 manipulationOriginalPosition = Vector3.zero;

    void INavigationHandler.OnNavigationStarted(NavigationEventData eventData)
    {
        InputManager.Instance.PushModalInputHandler(gameObject);
    }

    void INavigationHandler.OnNavigationUpdated(NavigationEventData eventData)
    {
        if (isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 2.c */

            // 2.c: Calculate a float rotationFactor based on eventData's NormalizedOffset.x multiplied by RotationSensitivity.
            // This will help control the amount of rotation.
            float rotationFactor = eventData.NormalizedOffset.x * RotationSensitivity;

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

    void INavigationHandler.OnNavigationCompleted(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void INavigationHandler.OnNavigationCanceled(NavigationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationStarted(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            InputManager.Instance.PushModalInputHandler(gameObject);

            manipulationOriginalPosition = transform.position;
        }
    }

    void IManipulationHandler.OnManipulationUpdated(ManipulationEventData eventData)
    {
        if (!isNavigationEnabled)
        {
            /* TODO: DEVELOPER CODING EXERCISE 4.a */

            // 4.a: Make this transform's position be the manipulationOriginalPosition + eventData.CumulativeDelta
            transform.position = manipulationOriginalPosition + eventData.CumulativeDelta;
        }
    }

    void IManipulationHandler.OnManipulationCompleted(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void IManipulationHandler.OnManipulationCanceled(ManipulationEventData eventData)
    {
        InputManager.Instance.PopModalInputHandler();
    }

    void ISpeechHandler.OnSpeechKeywordRecognized(SpeechEventData eventData)
    {
        if (eventData.RecognizedText.Equals("Move Astronaut"))
        {
            isNavigationEnabled = false;
        }
        else if (eventData.RecognizedText.Equals("Rotate Astronaut"))
        {
            isNavigationEnabled = true;
        }
        else
        {
            return;
        }

        eventData.Use();
    }
}

Skapa och distribuera

  • Återskapa i Unity och skapa och distribuera sedan från Visual Studio för att köra appen i HoloLens.
  • Flytta din hand framför HoloLens och höj pekfingret så att den kan spåras.
  • Fokusera markören över astronauten.
  • Säg "Flytta astronaut" för att flytta astronauten med en manipulationsgest.
  • Fyra pilar bör visas runt markören för att indikera att programmet nu svarar på manipulationshändelser.
  • Sänk indexfingret till din tumme och håll ihop dem.
  • När du flyttar runt din hand flyttas astronauten också (det här är manipulation).
  • Höj ditt indexfingr för att sluta manipulera astronauten.
  • Obs! Om du inte säger "Flytta astronaut" innan du flyttar din hand används navigeringsgesten i stället.
  • Säg "Rotera astronauten" för att återgå till det roterbara tillståndet.

Kapitel 5 – Modellexpansion

Mål

  • Expandera astronautmodellen till flera, mindre delar som användaren kan interagera med.
  • Flytta varje del individuellt med hjälp av gester för navigering och manipulering.

Instruktioner

I det här avsnittet utför vi följande uppgifter:

  1. Lägg till det nya nyckelordet "Expand Model" (Expandera modell) för att expandera astronautmodellen.
  2. Lägg till ett nytt nyckelord , "Reset Model"(Återställ modell) för att returnera modellen till dess ursprungliga form.

Vi gör detta genom att lägga till ytterligare två nyckelord i talindatakällan från föregående kapitel. Vi visar också ett annat sätt att hantera igenkänningshändelser.

  1. Klicka på AstronautManager i Kontroll och expandera avsnittet Nyckelord i Kontroll.
  2. Klicka på + till höger för att lägga till ett nytt nyckelord.
  3. Skriv nyckelordet som Expandera modell. Lägg gärna till en nyckelgenväg om du vill.
  4. Klicka på + till höger för att lägga till ett nytt nyckelord.
  5. Ange nyckelordet som Återställningsmodell. Lägg gärna till en nyckelgenväg om du vill.
  6. I panelen Kontroll klickar du på knappen Lägg till komponent.
  7. I menyn skriver du i sökrutan Speech Input Handler. Välj sökresultatet.
  8. Kontrollera Är global lyssnare eftersom vi vill att dessa kommandon ska fungera oavsett vilket GameObject vi fokuserar på.
  9. Klicka på + knappen och välj Expandera modell i listrutan Nyckelord.
  10. Klicka på + under Svar och dra AstronautManager från hierarkin till fältet Inget (objekt).
  11. Klicka nu på listrutan Ingen funktion, välj AstronautManager och sedan ExpandModelCommand.
  12. Klicka på knappen För + talinmatningshanteraren och välj Återställ modell i listrutan Nyckelord.
  13. Klicka på + under Svar och dra AstronautManager från hierarkin till fältet Inget (objekt).
  14. Klicka nu på listrutan Ingen funktion, välj AstronautManager och sedan ResetModelCommand.

Konfigurera speech input source och handler för kapitel 5

Skapa och distribuera

  • Prova! Skapa och distribuera appen till HoloLens.
  • Säg Expandera modell för att se den expanderade astronautmodellen.
  • Använd Navigering för att rotera enskilda delar av astronautdräkten.
  • Säg Flytta astronaut och använd sedan Manipulation för att flytta enskilda delar av astronautdräkten.
  • Säg Rotate Astronaut (Rotera astronaut) för att rotera delarna igen.
  • Säg Återställ modell för att returnera astronauten till dess ursprungliga form.

Slutet

Grattis! Nu har du slutfört MR Input 211: Gesture.

  • Du vet hur du identifierar och svarar på handspårning, navigering och manipuleringshändelser.
  • Du förstår skillnaden mellan gester för navigering och manipulering.
  • Du vet hur du ändrar markören för att ge visuell feedback för när en hand identifieras, när en hand är på väg att gå förlorad och när ett objekt stöder olika interaktioner (navigering kontra manipulation).