HoloLens (första generationen) och Azure 309: Application Insights

Anteckning

Självstudierna Mixed Reality Academy har utformats med HoloLens (första generationen) och Mixed Reality integrerande headset i åtanke. Därför tycker vi att det är viktigt att låta de här självstudierna vara kvar för utvecklare som fortfarande behöver vägledning för att utveckla för dessa enheter. De här självstudierna uppdateras inte med de senaste verktygsuppsättningarna eller interaktionerna som används för HoloLens 2. De kommer att underhållas för att fortsätta arbeta på de enheter som stöds. Det kommer att finnas en ny serie självstudier som kommer att publiceras i framtiden som visar hur man utvecklar för HoloLens 2. Det här meddelandet uppdateras med en länk till dessa självstudier när de publiceras.

Välkomstskärmen för Mixed Reality Academy-självstudien.

I den här kursen får du lära dig hur du lägger till Application Insights-funktioner i ett mixed reality-program med hjälp av api:et Azure Application Insights för att samla in analyser om användarbeteende.

Application Insights är en Microsoft-tjänst som gör det möjligt för utvecklare att samla in analyser från sina program och hantera dem från en lätthanterad portal. Analysen kan vara allt från prestanda till anpassad information som du vill samla in. Mer information finns på sidan Application Insights.

Efter att ha slutfört den här kursen har du ett integrerande headsetprogram för mixad verklighet, som kommer att kunna göra följande:

  1. Tillåt att användaren tittar och rör sig i en scen.
  2. Utlös sändningen av analys till Application Insights-tjänsten med hjälp av Gaze och Proximity to in-scene objects (Blick och närhet till scenobjekt).
  3. Appen anropar också tjänsten och hämtar information om vilket objekt som har kontaktats mest av användaren under de senaste 24 timmarna. Objektet ändrar färgen till grönt.

Den här kursen lär dig hur du hämtar resultaten från Application Insights-tjänsten till ett Unity-baserat exempelprogram. Det är upp till dig att tillämpa dessa begrepp på ett anpassat program som du kanske skapar.

Stöd för enheter

Kurs HoloLens Integrerande headset
MR och Azure 309: Application Insights ✔️ ✔️

Anteckning

Den här kursen fokuserar främst på Windows Mixed Reality integrerande (VR) headset, men du kan också använda det du lär dig i den här kursen för att Microsoft HoloLens. När du följer kursen visas anteckningar om eventuella ändringar som du kan behöva använda för att stödja HoloLens. När du använder HoloLens kan du märka eko under röstinspelningen.

Förutsättningar

Anteckning

Den här självstudien är utformad för utvecklare som har grundläggande erfarenhet av Unity och C#. Tänk också på att kraven och de skriftliga instruktionerna i det här dokumentet representerar det som har testats och verifierats i skrivande stund (juli 2018). Du är fri att använda den senaste programvaran, som anges i artikeln installera verktyg , men det bör inte antas att informationen i denna kurs kommer att matcha perfekt vad du hittar i nyare programvara än vad som anges nedan.

Vi rekommenderar följande maskinvara och programvara för den här kursen:

Innan du börjar

För att undvika problem med att skapa det här projektet rekommenderar vi starkt att du skapar projektet i den här självstudien i en rotmapp eller nära rotmapp (långa mappsökvägar kan orsaka problem vid byggtiden).

Varning

Tänk på att data som går till Application Insights tar tid, så ha tålamod. Om du vill kontrollera om tjänsten har tagit emot dina data kan du läsa kapitel 14, som visar hur du navigerar i portalen.

Kapitel 1 – Azure-portalen

Om du vill använda Application Insights måste du skapa och konfigurera en Application Insights-tjänst i Azure Portal.

  1. Logga in på Azure Portal.

    Anteckning

    Om du inte redan har ett Azure-konto måste du skapa ett. Om du följer den här självstudien i ett klassrum eller en labbsituation ber du din lärare eller någon av rektorerna om hjälp med att konfigurera ditt nya konto.

  2. När du är inloggad klickar du på Nytt i det övre vänstra hörnet och söker efter Application Insights och klickar på Retur.

    Anteckning

    Ordet Ny kan ha ersatts med Skapa en resurs i nyare portaler.

    Skärmbild som visar Azure-portalen, Insight är markerad i fönstret Allt.

  3. Den nya sidan till höger innehåller en beskrivning av tjänsten Azure Application Insights. Längst ned till vänster på den här sidan väljer du knappen Skapa för att skapa en association med den här tjänsten.

    Skärmbild av Skärmen Application Insights, Skapa är markerad.

  4. När du har klickat på Skapa:

    1. Infoga önskat namn för den här tjänstinstansen.

    2. Som Programtyp väljer du Allmänt.

    3. Välj en lämplig prenumeration.

    4. Välj en resursgrupp eller skapa en ny. En resursgrupp är ett sätt att övervaka, kontrollera åtkomst, etablera och hantera fakturering för en samling Azure-tillgångar. Vi rekommenderar att du behåller alla Azure-tjänster som är associerade med ett enda projekt (till exempel dessa kurser) under en gemensam resursgrupp).

      Om du vill läsa mer om Azure-resursgrupper kan du läsa artikeln om resursgrupper.

    5. Välj en plats.

    6. Du måste också bekräfta att du har förstått de villkor som tillämpas på den här tjänsten.

    7. Välj Skapa.

      Skärmbild av Application Insights-fönstret. Namn och programtyp är markerade.

  5. När du har klickat på Skapa måste du vänta tills tjänsten har skapats. Det kan ta en minut.

  6. Ett meddelande visas i portalen när tjänstinstansen har skapats.

    Skärmbild som visar en del av menyfliksområdet. Meddelandeikonen är markerad.

  7. Välj meddelandena för att utforska din nya tjänstinstans.

    Skärmbild som visar dialogrutan Distributionen lyckades. Gå till resurs är markerad.

  8. Klicka på knappen Gå till resurs i meddelandet för att utforska din nya tjänstinstans. Du kommer till din nya Application Insights Service-instans .

    Skärmbild som visar Application Insights-tjänstinstansen där instansnamnet är MyNewInsight.

    Anteckning

    Håll den här webbsidan öppen och enkel att komma åt. Du kommer ofta tillbaka hit för att se de data som samlas in.

    Viktigt

    För att implementera Application Insights måste du använda tre (3) specifika värden: Instrumentationsnyckel, Program-ID och API-nyckel. Nedan visas hur du hämtar dessa värden från din tjänst. Se till att anteckna dessa värden på en tom sida i Anteckningar , eftersom du snart kommer att använda dem i koden.

  9. För att hitta instrumenteringsnyckeln måste du rulla nedåt i listan över tjänstfunktioner och välja Egenskaper. Fliken som visas visar tjänstnyckeln.

    Skärmbild som visar tjänstfunktioner, Egenskaper är markerat i avsnittet Konfigurera och Instrumenteringsnyckeln är markerad i huvudfönstret.

  10. Lite under Egenskaper hittar du API-åtkomst, som du måste klicka på. Panelen till höger anger appens program-ID .

    Skärmbild som visar tjänstfunktioner, en P I-åtkomst är markerad. Skapa en P I-nyckel och program-ID är markerade i huvudfönstret.

  11. När panelen Program-ID fortfarande är öppen klickar du på Skapa API-nyckel, som öppnar panelen Skapa API-nyckel .

    Skärmbild som visar panelen Skapa en P I-nyckel.

  12. I den nu öppna panelen Skapa API-nyckel skriver du en beskrivning och markerar de tre rutorna.

  13. Klicka på Generera nyckel. Din API-nyckel skapas och visas.

    Skärmbild av panelen Skapa en P I-nyckel som visar den nya tjänstnyckelinformationen.

    Varning

    Det här är den enda gången din tjänstnyckel visas, så se till att du gör en kopia av den nu.

Kapitel 2 – Konfigurera Unity-projektet

Följande är en typisk konfiguration för utveckling med mixad verklighet och är därför en bra mall för andra projekt.

  1. Öppna Unity och klicka på Nytt.

    Skärmbild av fönstret Unity-projekt. Ingen projektinformation visas.

  2. Nu måste du ange ett Unity-projektnamn, infoga MR_Azure_Application_Insights. Kontrollera att mallen är inställd på 3D. Ange plats till någonstans som passar dig (kom ihåg att närmare rotkataloger är bättre). Klicka sedan på Skapa projekt.

    Skärmbild av fönstret Nya Unity-projekt med projektinformation.

  3. När Unity är öppet är det värt att kontrollera att standardskriptredigeraren är inställd på Visual Studio. Gå till Redigera > inställningar och gå sedan till Externa verktyg från det nya fönstret. Ändra extern skriptredigerare till Visual Studio 2017. Stäng fönstret Inställningar .

    Skärmbild som visar att Visual Studio har konfigurerats som extern skriptredigerare.

  4. Gå sedan till Inställningar för filbygge > och växla plattformen till Universell Windows-plattform genom att klicka på knappen Växla plattform.

    Skärmbild av fönstret Build Settings (Skapa inställningar) som visar listan plattformsval. Universell Windows-plattform har valts.

  5. Gå till Inställningar för filbygge > och kontrollera att:

    1. Målenheten är inställd på Valfri enhet

      För Microsoft HoloLens anger du Målenhet till HoloLens.

    2. Byggtyp är inställt på D3D

    3. SDK är inställt på Senaste installerat

    4. Build and Run är inställt på Lokal dator

    5. Spara scenen och lägg till den i bygget.

      1. Gör detta genom att välja Lägg till öppna scener. Ett spara-fönster visas.

        Skärmbild av fönstret Build Settings (Skapa inställningar) och Lägg till öppna scener är markerat.

      2. Skapa en ny mapp för detta, och eventuella framtida scenarier, klicka sedan på knappen Ny mapp , för att skapa en ny mapp, ge den namnet Scener.

        Skärmbild av fönstret Spara scen, mappen Scener är markerad.

      3. Öppna mappen Scener och skriv ApplicationInsightsScene i textfältet Filnamn: och klicka sedan på Spara.

        Skärmbild av fönstret Spara scen med filnamnet angivet.

  6. De återstående inställningarna i Bygginställningar bör vara kvar som standard för tillfället.

  7. I fönstret Build Settings (Skapa inställningar ) väljer du Spelarinställningar. Då öppnas den relaterade panelen i det utrymme där inspektören finns.

    Skärmbild av fliken Kontroll som visar spelarinställningar.

  8. I den här panelen måste några inställningar verifieras:

    1. På fliken Andra inställningar :

      1. Skriptkörningsversionen bör vara experimentell (.NET 4.6 Motsvarande), vilket utlöser ett behov av att starta om redigeraren.

      2. Skriptserverdelen ska vara .NET

      3. API-kompatibilitetsnivån ska vara .NET 4.6

      Skärmbild av fliken Kontroll som visar information i konfigurationsavsnittet i Andra inställningar.

    2. På fliken Publiceringsinställningar går du till Funktioner och kontrollerar:

      • InternetClient

        Skärmbild av listan Funktioner, Internetklienten är markerad.

    3. Längre ned på panelen, i XR-inställningar (finns nedan Publiceringsinställningar), markerar du Virtual Reality Supported (Virtual Reality Supported) och kontrollerar att Windows Mixed Reality SDK har lagts till.

      Skärmbild av avsnittet X R-inställningar, Virtual Reality Supported (Virtuell verklighet stöds) är markerat.

  9. I Bygginställningar är Unity C# Projects inte längre nedtonat. markera kryssrutan bredvid detta.

  10. Stäng fönstret Build Settings (Bygginställningar).

  11. Spara din scen och ditt projekt (FILE>SAVE SCENE/FILE>SAVE PROJECT).

Kapitel 3 – Importera Unity-paketet

Viktigt

Om du vill hoppa över Unity Set up-komponenterna i den här kursen och fortsätta direkt till koden kan du ladda ned den här Azure-MR-309.unitypackage genom att importera den till ditt projekt som ett anpassat paket. Detta kommer också att innehålla DLL:er från nästa kapitel. Efter importen fortsätter du från kapitel 6.

Viktigt

Om du vill använda Application Insights i Unity måste du importera DLL-filen för den, tillsammans med Newtonsoft DLL. Det finns för närvarande ett känt problem i Unity som kräver att plugin-program konfigureras om efter importen. De här stegen (4–7 i det här avsnittet) krävs inte längre när felet har lösts.

Om du vill importera Application Insights till ditt eget projekt kontrollerar du att du har laddat ned ".unitypackage", som innehåller plugin-programmen. Gör sedan följande:

  1. Lägg till.unitypackage** i Unity med menyalternativet Importera paket > för tillgångar>.

  2. I rutan Importera Unity-paket som visas kontrollerar du att allt under (och inklusive) plugin-program är markerat.

    Skärmbild av dialogrutan Importera Unity-paket som visar alla objekt markerade.

  3. Klicka på knappen Importera för att lägga till objekten i projektet.

  4. Gå till mappen Insights under Plugin-program i projektvyn och välj endast följande plugin-program:

    • Microsoft.ApplicationInsights

    Skärmbild av projektpanelen, mappen Insights är öppen.

  5. När du har valt det här plugin-programmet kontrollerar du att Alla plattformar är avmarkerade och kontrollerar sedan att WSAPlayer också är avmarkerat och klickar sedan på Använd. Detta är bara för att bekräfta att filerna är korrekt konfigurerade.

    Skärmbild av panelen Inspector som visar redigeraren och fristående markerad.

    Anteckning

    Om plugin-programmen markeras så här konfigureras de så att de endast används i Unity-redigeraren. Det finns en annan uppsättning DLL:er i WSA-mappen som ska användas när projektet har exporterats från Unity.

  6. Därefter måste du öppna WSA-mappen i mappen Insights . Du ser en kopia av samma fil som du har konfigurerat. Välj den här filen och kontrollera sedan att Alla plattformar är avmarkerade i inspektören och se sedan till att endastWSAPlayerär markerat. Klicka på Applicera.

    Skärmbild av panelen Inspector som visar att W S A Player har markerats.

  7. Nu måste du följa steg 4–6, men för Newtonsoft-plugin-programmet i stället. Se skärmbilden nedan för hur resultatet ska se ut.

    Skärmbild av fyra vyer av projekt- och kontrollpanelerna som visar resultatet av konfigurationen av Newtonsoft-mappen och valet av plugin-program.

Kapitel 4 – Konfigurera kamera- och användarkontroller

I det här kapitlet konfigurerar du kameran och kontrollerna så att användaren kan se och flytta i scenen.

  1. Högerklicka i ett tomt område på hierarkipanelen och sedan på Skapa>tom.

    Skärmbild av hierarkipanelen, Skapa tom är markerad.

  2. Byt namn på den nya tomma GameObject till Kamera överordnad.

    Skärmbild av hierarkipanelen med Kamera överordnad markerad. Panelen Inspector

  3. Högerklicka i ett tomt område i hierarkipanelen och sedan på 3D-objekt och sedan på Sphere.

  4. Byt namn på sfären till höger.

  5. Ange transformeringsskalan för den högra handen till 0,1, 0,1, 0,1

    Skärmbild av panelerna Hierarki och Kontroll, avsnittet Transformera på panelen Kontroll är markerat.

  6. Ta bort komponenten Sphere Collider från höger hand genom att klicka på kugghjulet i komponenten Sphere Collider och sedan ta bort komponenten.

    Skärmbild av panelen Inspector, kugghjulsikonen och Ta bort komponent markeras i avsnittet Sphere Collider.

  7. Dra huvudkameran och objekten till höger på hierarkipanelen till objektet Kamera överordnad .

    Skärmbild av hierarkipanelen med Huvudkamera markerad, panelen Kontroll visar Main Camera markerat.

  8. Ange transformeringspositionen för både huvudkameran och objektet Till höger till 0, 0, 0.

    Skärmbild av hierarkipanelen med Huvudkamera markerad, Transformeringsinställningar är markerade i panelen Kontroll.

    Skärmbild av panelen Hierarki med Höger hand markerat, Transformeringsinställningar är markerade i panelen Kontroll.

Kapitel 5 – Konfigurera objekten i Unity-scenen

Nu ska du skapa några grundläggande former för scenen, som användaren kan interagera med.

  1. Högerklicka i ett tomt område på hierarkipanelen och välj sedan Plane3D-objekt.

  2. Ange planets transformeringsposition till 0, -1, 0.

  3. Ange Skala för plantransformering till 5, 1, 5.

    Skärmbild av panelerna Scen, Hierarki och Kontroll. Avsnittet Transformera på panelen Kontroll är markerat.

  4. Skapa ett grundläggande material att använda med plane-objektet , så att de andra formerna blir lättare att se. Gå till projektpanelen, högerklicka och skapa sedan Skapa, följt av Mapp, för att skapa en ny mapp. Ge den namnet Material.

    Skärmbild av projektpanelen med Skapa och mapp markerat.Skärmbild av projektpanelen. Material är markerat i fönstret Tillgångar.

  5. Öppna mappen Material , högerklicka, klicka på Skapa och sedan på Material för att skapa ett nytt material. Ge den namnet Blå.

    Skärmbild av projektpanelen med Skapa och material markerat.Skärmbild av projektpanelen. Blått är markerat i fönstret Material.

  6. När det nya blå materialet har valts tittar du på Inspector och klickar på det rektangulära fönstret tillsammans med Albedo. Välj en blå färg (den enda bilden nedan är Hexfärg: #3592FFFF). Klicka på knappen Stäng när du har valt.

    Skärmbild av panelen Inspector. Färgavsnittet är markerat.

  7. Dra ditt nya material från mappen Material till det nya planet i scenen (eller släpp det på Plane-objektet i hierarkin).

    Skärmbild av panelen Scen som visar det nya materialet från mappen Material.

  8. Högerklicka i ett tomt område på hierarkipanelen och sedan på 3D-objekt, Capsule.

    • Med kapseln vald ändrar du dess transformeringsposition till: -10, 1, 0.
  9. Högerklicka i ett tomt område på hierarkipanelen och sedan på 3D-objekt, kub.

    • När kuben är markerad ändrar du dess transformeringsposition till: 0, 0, 10.
  10. Högerklicka i ett tomt område på hierarkipanelen och sedan på 3D-objekt, sfär.

    • Ändra dess transformeringsposition till: 10, 0, 0 med sfären markerad.

    Skärmbild av panelerna Scen, Hierarki och Kontroll. Capsule har valts på panelen Hierarki.

    Anteckning

    Dessa positionsvärden är förslag. Du kan ställa in positionerna för objekten till vad du vill, även om det är lättare för användaren av programmet om objekt avstånd inte är för långt från kameran.

  11. När programmet körs måste det kunna identifiera objekten i scenen. För att uppnå detta måste de taggas. Välj ett av objekten och klicka på Lägg till tagg i panelen Kontroll. Då växlar du Kontrollanten mot panelen Taggar & Lager.

    Skärmbild av panelen Inspector som visar alternativet Lägg till tagg markerat.Skärmbild av panelen Kontroll som visar Taggar och lager markerade.

  12. Klicka på symbolen + (plus) och skriv sedan taggnamnet ObjectInScene.

    Skärmbild av panelen Kontroll med Taggar och lager markerade. Dialogrutan Nytt taggnamn är markerad.

    Varning

    Om du använder ett annat namn för taggen måste du se till att den här ändringen även görs till skripten DataFromAnalytics, ObjectTrigger och Gaze senare, så att objekten hittas och identifieras i scenen.

  13. När taggen har skapats måste du tillämpa den på alla tre objekten. I hierarkin håller du ned Skift-tangenten och klickar sedan på objekten Capsule, Cube och Sphere. I Inspector klickar du sedan på listrutemenyn tillsammans med Tagg och sedan på taggen ObjectInScene som du skapade.

    Skärmbild av panelen Inspector, en pil som pekar på Tagg. På den otaggade menyn visas Otaggade markerade och ObjectInScene har valts.Skärmbild som visar två menyer med Skapa och Mapp markerat.

Kapitel 6 – Skapa klassen ApplicationInsightsTracker

Det första skriptet du behöver skapa är ApplicationInsightsTracker, som ansvarar för:

  1. Skapa händelser baserat på användarinteraktioner som ska skickas till Azure Application Insights.

  2. Skapa lämpliga händelsenamn, beroende på användarinteraktion.

  3. Skicka händelser till Application Insights Service-instansen.

Så här skapar du den här klassen:

  1. Högerklicka på projektpanelen och sedan på Skapa>mapp. Ge mappen namnet Skript.

    Skärmbild av panelen Projekt. Mappikonen Skript är markerad i fönstret Tillgångar.Skärmbild som visar menyalternativ där alternativen Skapa och C#-skript är markerade.

  2. När mappen Skript har skapats dubbelklickar du på den för att öppna den. Högerklicka sedan på Skapa>C#-skript i mappen. Ge skriptet namnet ApplicationInsightsTracker.

  3. Dubbelklicka på det nya ApplicationInsightsTracker-skriptet för att öppna det med Visual Studio.

  4. Uppdatera namnrymder överst i skriptet så att de ser ut så här:

        using Microsoft.ApplicationInsights;
        using Microsoft.ApplicationInsights.DataContracts;
        using Microsoft.ApplicationInsights.Extensibility;
        using UnityEngine;
    
  5. Infoga följande variabler i klassen:

        /// <summary>
        /// Allows this class to behavior like a singleton
        /// </summary>
        public static ApplicationInsightsTracker Instance;
    
        /// <summary>
        /// Insert your Instrumentation Key here
        /// </summary>
        internal string instrumentationKey = "Insert Instrumentation Key here";
    
        /// <summary>
        /// Insert your Application Id here
        /// </summary>
        internal string applicationId = "Insert Application Id here";
    
        /// <summary>
        /// Insert your API Key here
        /// </summary>
        internal string API_Key = "Insert API Key here";
    
        /// <summary>
        /// Represent the Analytic Custom Event object
        /// </summary>
        private TelemetryClient telemetryClient;
    
        /// <summary>
        /// Represent the Analytic object able to host gaze duration
        /// </summary>
        private MetricTelemetry metric;
    

    Anteckning

    Ange värdena instrumentationKey, applicationId och API_Key på rätt sätt med hjälp av tjänstnycklarna från Azure-portalen enligt kapitel 1, steg 9 och senare.

  6. Lägg sedan till metoderna Start() och Awake(), som anropas när klassen initieras:

        /// <summary>
        /// Sets this class instance as a singleton
        /// </summary>
        void Awake()
        {
            Instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {
            // Instantiate telemetry and metric
            telemetryClient = new TelemetryClient();
    
            metric = new MetricTelemetry();
    
            // Assign the Instrumentation Key to the Event and Metric objects
            TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;
    
            telemetryClient.InstrumentationKey = instrumentationKey;
        }
    
  7. Lägg till de metoder som ansvarar för att skicka händelser och mått som registrerats av ditt program:

        /// <summary>
        /// Submit the Event to Azure Analytics using the event trigger object
        /// </summary>
        public void RecordProximityEvent(string objectName)
        {
            telemetryClient.TrackEvent(CreateEventName(objectName));
        }
    
        /// <summary>
        /// Uses the name of the object involved in the event to create 
        /// and return an Event Name convention
        /// </summary>
        public string CreateEventName(string name)
        {
            string eventName = $"User near {name}";
            return eventName;
        }
    
        /// <summary>
        /// Submit a Metric to Azure Analytics using the metric gazed object
        /// and the time count of the gaze
        /// </summary>
        public void RecordGazeMetrics(string objectName, int time)
        {
            // Output Console information about gaze.
            Debug.Log($"Finished gazing at {objectName}, which went for <b>{time}</b> second{(time != 1 ? "s" : "")}");
    
            metric.Name = $"Gazed {objectName}";
    
            metric.Value = time;
    
            telemetryClient.TrackMetric(metric);
        }
    
  8. Se till att spara ändringarna i Visual Studio innan du återgår till Unity.

Kapitel 7 – Skapa Gaze-skriptet

Nästa skript att skapa är Gaze-skriptet . Det här skriptet ansvarar för att skapa en Raycast som ska projiceras framåt från huvudkameran för att identifiera vilket objekt användaren tittar på. I det här fallet måste Raycast identifiera om användaren tittar på ett objekt med taggen ObjectInScene och sedan räkna hur länge användaren tittar på objektet.

  1. Dubbelklicka på mappen Skript för att öppna den.

  2. Högerklicka i mappen Skript och klicka på Skapa>C#-skript. Ge skriptet namnet Gaze.

  3. Dubbelklicka på skriptet för att öppna det med Visual Studio.

  4. Ersätt den befintliga koden med följande:

        using UnityEngine;
    
        public class Gaze : MonoBehaviour
        {
            /// <summary>
            /// Provides Singleton-like behavior to this class.
            /// </summary>
            public static Gaze Instance;
    
            /// <summary>
            /// Provides a reference to the object the user is currently looking at.
            /// </summary>
            public GameObject FocusedGameObject { get; private set; }
    
            /// <summary>
            /// Provides whether an object has been successfully hit by the raycast.
            /// </summary>
            public bool Hit { get; private set; }
    
            /// <summary>
            /// Provides a reference to compare whether the user is still looking at 
            /// the same object (and has not looked away).
            /// </summary>
            private GameObject _oldFocusedObject = null;
    
            /// <summary>
            /// Max Ray Distance
            /// </summary>
            private float _gazeMaxDistance = 300;
    
            /// <summary>
            /// Max Ray Distance
            /// </summary>
            private float _gazeTimeCounter = 0;
    
            /// <summary>
            /// The cursor object will be created when the app is running,
            /// this will store its values. 
            /// </summary>
            private GameObject _cursor;
        }
    
  5. Kod för metoderna Awake() och Start() måste nu läggas till.

        private void Awake()
        {
            // Set this class to behave similar to singleton
            Instance = this;
            _cursor = CreateCursor();
        }
    
        void Start()
        {
            FocusedGameObject = null;
        }
    
        /// <summary>
        /// Create a cursor object, to provide what the user
        /// is looking at.
        /// </summary>
        /// <returns></returns>
        private GameObject CreateCursor()    
        {
            GameObject newCursor = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    
            // Remove the collider, so it does not block raycast.
            Destroy(newCursor.GetComponent<SphereCollider>());
    
            newCursor.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
    
            newCursor.GetComponent<MeshRenderer>().material.color = 
            Color.HSVToRGB(0.0223f, 0.7922f, 1.000f);
    
            newCursor.SetActive(false);
            return newCursor;
        }
    
  6. I klassen Gaze lägger du till följande kod i metoden Update() för att projicera en Raycast och identifiera målträffen:

        /// <summary>
        /// Called every frame
        /// </summary>
        void Update()
        {
            // Set the old focused gameobject.
            _oldFocusedObject = FocusedGameObject;
    
            RaycastHit hitInfo;
    
            // Initialize Raycasting.
            Hit = Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hitInfo, _gazeMaxDistance);
    
            // Check whether raycast has hit.
            if (Hit == true)
            {
                // Check whether the hit has a collider.
                if (hitInfo.collider != null)
                {
                    // Set the focused object with what the user just looked at.
                    FocusedGameObject = hitInfo.collider.gameObject;
    
                    // Lerp the cursor to the hit point, which helps to stabilize the gaze.
                    _cursor.transform.position = Vector3.Lerp(_cursor.transform.position, hitInfo.point, 0.6f);
    
                    _cursor.SetActive(true);
                }
                else
                {
                    // Object looked on is not valid, set focused gameobject to null.
                    FocusedGameObject = null;
    
                    _cursor.SetActive(false);
                }
            }
            else
            {
                // No object looked upon, set focused gameobject to null.
                FocusedGameObject = null;
    
                _cursor.SetActive(false);
            }
    
            // Check whether the previous focused object is this same object. If so, reset the focused object.
            if (FocusedGameObject != _oldFocusedObject)
            {
                ResetFocusedObject();
            }
            // If they are the same, but are null, reset the counter. 
            else if (FocusedGameObject == null && _oldFocusedObject == null)
            {
                _gazeTimeCounter = 0;
            }
            // Count whilst the user continues looking at the same object.
            else
            {
                _gazeTimeCounter += Time.deltaTime;
            }
        }
    
  7. Lägg till metoden ResetFocusedObject() för att skicka data till Application Insights när användaren har tittat på ett objekt.

        /// <summary>
        /// Reset the old focused object, stop the gaze timer, and send data if it
        /// is greater than one.
        /// </summary>
        public void ResetFocusedObject()
        {
            // Ensure the old focused object is not null.
            if (_oldFocusedObject != null)
            {
                // Only looking for objects with the correct tag.
                if (_oldFocusedObject.CompareTag("ObjectInScene"))
                {
                    // Turn the timer into an int, and ensure that more than zero time has passed.
                    int gazeAsInt = (int)_gazeTimeCounter;
    
                    if (gazeAsInt > 0)
                    {
                        //Record the object gazed and duration of gaze for Analytics
                        ApplicationInsightsTracker.Instance.RecordGazeMetrics(_oldFocusedObject.name, gazeAsInt);
                    }
                    //Reset timer
                    _gazeTimeCounter = 0;
                }
            }
        }
    
  8. Nu har du slutfört Gaze-skriptet . Spara ändringarna i Visual Studio innan du återgår till Unity.

Kapitel 8 – Skapa klassen ObjectTrigger

Nästa skript som du behöver skapa är ObjectTrigger, som ansvarar för:

  • Lägga till komponenter som behövs för kollision till huvudkameran.
  • Identifierar om kameran är nära ett objekt som är taggat som ObjectInScene.

Så här skapar du skriptet:

  1. Dubbelklicka på mappen Skript för att öppna den.

  2. Högerklicka i mappen Skript och klicka på Skapa>C#-skript. Ge skriptet namnet ObjectTrigger.

  3. Dubbelklicka på skriptet för att öppna det med Visual Studio. Ersätt den befintliga koden med följande:

        using UnityEngine;
    
        public class ObjectTrigger : MonoBehaviour
        {
            private void Start()
            {
                // Add the Collider and Rigidbody components, 
                // and set their respective settings. This allows for collision.
                gameObject.AddComponent<SphereCollider>().radius = 1.5f;
    
                gameObject.AddComponent<Rigidbody>().useGravity = false;
            }
    
            /// <summary>
            /// Triggered when an object with a collider enters this objects trigger collider.
            /// </summary>
            /// <param name="collision">Collided object</param>
            private void OnCollisionEnter(Collision collision)
            {
                CompareTriggerEvent(collision, true);
            }
    
            /// <summary>
            /// Triggered when an object with a collider exits this objects trigger collider.
            /// </summary>
            /// <param name="collision">Collided object</param>
            private void OnCollisionExit(Collision collision)
            {
                CompareTriggerEvent(collision, false);
            }
    
            /// <summary>
            /// Method for providing debug message, and sending event information to InsightsTracker.
            /// </summary>
            /// <param name="other">Collided object</param>
            /// <param name="enter">Enter = true, Exit = False</param>
            private void CompareTriggerEvent(Collision other, bool enter)
            {
                if (other.collider.CompareTag("ObjectInScene"))
                {
                    string message = $"User is{(enter == true ? " " : " no longer ")}near <b>{other.gameObject.name}</b>";
    
                    if (enter == true)
                    {
                        ApplicationInsightsTracker.Instance.RecordProximityEvent(other.gameObject.name);
                    }
                    Debug.Log(message);
                }
            }
        }
    
  4. Se till att spara ändringarna i Visual Studio innan du återgår till Unity.

Kapitel 9 – Skapa klassen DataFromAnalytics

Nu måste du skapa skriptet DataFromAnalytics , som ansvarar för:

  • Hämtar analysdata om vilket objekt som har använts mest av kameran.
  • Med hjälp av tjänstnycklar, som tillåter kommunikation med din Azure Application Insights Service-instans.
  • Sortera objekten i scenen, enligt vilka har det högsta antalet händelser.
  • Ändra materialfärgen, för det mest använda objektet, till grön.

Så här skapar du skriptet:

  1. Dubbelklicka på mappen Skript för att öppna den.

  2. Högerklicka i mappen Skript och klicka på Skapa>C#-skript. Ge skriptet namnet DataFromAnalytics.

  3. Dubbelklicka på skriptet för att öppna det med Visual Studio.

  4. Infoga följande namnområden:

        using Newtonsoft.Json;
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. Infoga följande i skriptet:

        /// <summary>
        /// Number of most recent events to be queried
        /// </summary>
        private int _quantityOfEventsQueried = 10;
    
        /// <summary>
        /// The timespan with which to query. Needs to be in hours.
        /// </summary>
        private int _timepspanAsHours = 24;
    
        /// <summary>
        /// A list of the objects in the scene
        /// </summary>
        private List<GameObject> _listOfGameObjectsInScene;
    
        /// <summary>
        /// Number of queries which have returned, after being sent.
        /// </summary>
        private int _queriesReturned = 0;
    
        /// <summary>
        /// List of GameObjects, as the Key, with their event count, as the Value.
        /// </summary>
        private List<KeyValuePair<GameObject, int>> _pairedObjectsWithEventCount = new List<KeyValuePair<GameObject, int>>();
    
        // Use this for initialization
        void Start()
        {
            // Find all objects in scene which have the ObjectInScene tag (as there may be other GameObjects in the scene which you do not want).
            _listOfGameObjectsInScene = GameObject.FindGameObjectsWithTag("ObjectInScene").ToList();
    
            FetchAnalytics();
        }
    
  6. I klassen DataFromAnalytics , direkt efter metoden Start(), lägger du till följande metod med namnet FetchAnalytics(). Den här metoden ansvarar för att fylla i listan över nyckel/värde-par med ett GameObject och ett antal platshållarhändelser. Sedan initieras Coroutine för GetWebRequest(). Frågestrukturen för anropet till Application Insights finns också i den här metoden som fråge-URL-slutpunkt .

        private void FetchAnalytics()
        {
            // Iterate through the objects in the list
            for (int i = 0; i < _listOfGameObjectsInScene.Count; i++)
            {
                // The current event number is not known, so set it to zero.
                int eventCount = 0;
    
                // Add new pair to list, as placeholder, until eventCount is known.
                _pairedObjectsWithEventCount.Add(new KeyValuePair<GameObject, int>(_listOfGameObjectsInScene[i], eventCount));
    
                // Set the renderer of the object to the default color, white
                _listOfGameObjectsInScene[i].GetComponent<Renderer>().material.color = Color.white;
    
                // Create the appropriate object name using Insights structure
                string objectName = _listOfGameObjectsInScene[i].name;
    
     		    // Build the queryUrl for this object.
     		    string queryUrl = Uri.EscapeUriString(string.Format(
                    "https://api.applicationinsights.io/v1/apps/{0}/events/$all?timespan=PT{1}H&$search={2}&$select=customMetric/name&$top={3}&$count=true",
     			    ApplicationInsightsTracker.Instance.applicationId, _timepspanAsHours, "Gazed " + objectName, _quantityOfEventsQueried));
    
    
                // Send this object away within the WebRequest Coroutine, to determine it is event count.
                StartCoroutine("GetWebRequest", new KeyValuePair<string, int>(queryUrl, i));
            }
        }
    
  7. Precis under metoden FetchAnalytics() lägger du till en metod med namnet GetWebRequest(), som returnerar en IEnumerator. Den här metoden ansvarar för att begära hur många gånger en händelse, motsvarande en specifik GameObject, har anropats i Application Insights. När alla skickade frågor har returnerats anropas metoden DetermineWinner().

        /// <summary>
        /// Requests the data count for number of events, according to the
        /// input query URL.
        /// </summary>
        /// <param name="webQueryPair">Query URL and the list number count.</param>
        /// <returns></returns>
        private IEnumerator GetWebRequest(KeyValuePair<string, int> webQueryPair)
        {
            // Set the URL and count as their own variables (for readability).
            string url = webQueryPair.Key;
            int currentCount = webQueryPair.Value;
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(url))
            {
                DownloadHandlerBuffer handlerBuffer = new DownloadHandlerBuffer();
    
                unityWebRequest.downloadHandler = handlerBuffer;
    
                unityWebRequest.SetRequestHeader("host", "api.applicationinsights.io");
    
                unityWebRequest.SetRequestHeader("x-api-key", ApplicationInsightsTracker.Instance.API_Key);
    
                yield return unityWebRequest.SendWebRequest();
    
                if (unityWebRequest.isNetworkError)
                {
                    // Failure with web request.
                    Debug.Log("<color=red>Error Sending:</color> " + unityWebRequest.error);
                }
                else
                {
                    // This query has returned, so add to the current count.
                    _queriesReturned++;
    
                    // Initialize event count integer.
                    int eventCount = 0;
    
                    // Deserialize the response with the custom Analytics class.
                    Analytics welcome = JsonConvert.DeserializeObject<Analytics>(unityWebRequest.downloadHandler.text);
    
                    // Get and return the count for the Event
                    if (int.TryParse(welcome.OdataCount, out eventCount) == false)
                    {
                        // Parsing failed. Can sometimes mean that the Query URL was incorrect.
                        Debug.Log("<color=red>Failure to Parse Data Results. Check Query URL for issues.</color>");
                    }
                    else
                    {
                        // Overwrite the current pair, with its actual values, now that the event count is known.
                        _pairedObjectsWithEventCount[currentCount] = new KeyValuePair<GameObject, int>(_pairedObjectsWithEventCount[currentCount].Key, eventCount);
                    }
    
                    // If all queries (compared with the number which was sent away) have 
                    // returned, then run the determine winner method. 
                    if (_queriesReturned == _pairedObjectsWithEventCount.Count)
                    {
                        DetermineWinner();
                    }
                }
            }
        }
    
  8. Nästa metod är DetermineWinner(), som sorterar listan över GameObject - och Int-par , enligt det högsta antalet händelser. Det ändrar sedan materialfärgen för det GameObject till grönt (som feedback för att det har det högsta antalet). Då visas ett meddelande med analysresultatet.

        /// <summary>
        /// Call to determine the keyValue pair, within the objects list, 
        /// with the highest event count.
        /// </summary>
        private void DetermineWinner()
        {
            // Sort the values within the list of pairs.
            _pairedObjectsWithEventCount.Sort((x, y) => y.Value.CompareTo(x.Value));
    
            // Change its colour to green
            _pairedObjectsWithEventCount.First().Key.GetComponent<Renderer>().material.color = Color.green;
    
            // Provide the winner, and other results, within the console window. 
            string message = $"<b>Analytics Results:</b>\n " +
                $"<i>{_pairedObjectsWithEventCount.First().Key.name}</i> has the highest event count, " +
                $"with <i>{_pairedObjectsWithEventCount.First().Value.ToString()}</i>.\nFollowed by: ";
    
            for (int i = 1; i < _pairedObjectsWithEventCount.Count; i++)
            {
                message += $"{_pairedObjectsWithEventCount[i].Key.name}, " +
                    $"with {_pairedObjectsWithEventCount[i].Value.ToString()} events.\n";
            }
    
            Debug.Log(message);
        }
    
  9. Lägg till den klassstruktur som ska användas för att deserialisera JSON-objektet som tas emot från Application Insights. Lägg till dessa klasser längst ned i din DataFromAnalytics-klassfil, utanför klassdefinitionen.

        /// <summary>
        /// These classes represent the structure of the JSON response from Azure Insight
        /// </summary>
        [Serializable]
        public class Analytics
        {
            [JsonProperty("@odata.context")]
            public string OdataContext { get; set; }
    
            [JsonProperty("@odata.count")]
            public string OdataCount { get; set; }
    
            [JsonProperty("value")]
            public Value[] Value { get; set; }
        }
    
        [Serializable]
        public class Value
        {
            [JsonProperty("customMetric")]
            public CustomMetric CustomMetric { get; set; }
        }
    
        [Serializable]
        public class CustomMetric
        {
            [JsonProperty("name")]
            public string Name { get; set; }
        }
    
  10. Se till att spara ändringarna i Visual Studio innan du återvänder till Unity.

Kapitel 10 – Skapa klassen Rörelse

Rörelseskriptet är nästa skript som du behöver skapa. Den ansvarar för:

  • Flytta huvudkameran enligt den riktning som kameran tittar mot.
  • Lägga till alla andra skript i scenobjekt.

Så här skapar du skriptet:

  1. Dubbelklicka på mappen Skript för att öppna den.

  2. Högerklicka i mappen Skript och klicka på Skapa>C#-skript. Ge skriptet namnet Movement.

  3. Dubbelklicka på skriptet för att öppna det med Visual Studio.

  4. Ersätt den befintliga koden med följande:

        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
    
        public class Movement : MonoBehaviour
        {
            /// <summary>
            /// The rendered object representing the right controller.
            /// </summary>
            public GameObject Controller;
    
            /// <summary>
            /// The movement speed of the user.
            /// </summary>
            public float UserSpeed;
    
            /// <summary>
            /// Provides whether source updates have been registered.
            /// </summary>
            private bool _isAttached = false;
    
            /// <summary>
            /// The chosen controller hand to use. 
            /// </summary>
            private InteractionSourceHandedness _handness = InteractionSourceHandedness.Right;
    
            /// <summary>
            /// Used to calculate and proposes movement translation.
            /// </summary>
            private Vector3 _playerMovementTranslation;
    
            private void Start()
            {
                // You are now adding components dynamically 
                // to ensure they are existing on the correct object  
    
                // Add all camera related scripts to the camera. 
                Camera.main.gameObject.AddComponent<Gaze>();
                Camera.main.gameObject.AddComponent<ObjectTrigger>();
    
                // Add all other scripts to this object.
                gameObject.AddComponent<ApplicationInsightsTracker>();
                gameObject.AddComponent<DataFromAnalytics>();
            }
    
            // Update is called once per frame
            void Update()
            {
    
            }
        }
    
  5. I klassen Rörelse, under den tomma metoden Update(), infogar du följande metoder som gör att användaren kan använda handstyrenheten för att flytta i det virtuella utrymmet:

        /// <summary>
        /// Used for tracking the current position and rotation of the controller.
        /// </summary>
        private void UpdateControllerState()
        {
    #if UNITY_WSA && UNITY_2017_2_OR_NEWER
            // Check for current connected controllers, only if WSA.
            string message = string.Empty;
    
            if (InteractionManager.GetCurrentReading().Length > 0)
            {
                foreach (var sourceState in InteractionManager.GetCurrentReading())
                {
                    if (sourceState.source.kind == InteractionSourceKind.Controller && sourceState.source.handedness == _handness)
                    {
                        // If a controller source is found, which matches the selected handness, 
                        // check whether interaction source updated events have been registered. 
                        if (_isAttached == false)
                        {
                            // Register events, as not yet registered.
                            message = "<color=green>Source Found: Registering Controller Source Events</color>";
                            _isAttached = true;
    
                            InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated;
                        }
    
                        // Update the position and rotation information for the controller.
                        Vector3 newPosition;
                        if (sourceState.sourcePose.TryGetPosition(out newPosition, InteractionSourceNode.Pointer) && ValidPosition(newPosition))
                        {
                            Controller.transform.localPosition = newPosition;
                        }
    
                        Quaternion newRotation;
    
                        if (sourceState.sourcePose.TryGetRotation(out newRotation, InteractionSourceNode.Pointer) && ValidRotation(newRotation))
                        {
                            Controller.transform.localRotation = newRotation;
                        }
                    }
                }
            }
            else
            {
                // Controller source not detected. 
                message = "<color=blue>Trying to detect controller source</color>";
    
                if (_isAttached == true)
                {
                    // A source was previously connected, however, has been lost. Disconnected
                    // all registered events. 
    
                    _isAttached = false;
    
                    InteractionManager.InteractionSourceUpdated -= InteractionManager_InteractionSourceUpdated;
    
                    message = "<color=red>Source Lost: Detaching Controller Source Events</color>";
                }
            }
    
            if(message != string.Empty)
            {
                Debug.Log(message);
            }
    #endif
        }
    
        /// <summary>
        /// This registered event is triggered when a source state has been updated.
        /// </summary>
        /// <param name="obj"></param>
        private void InteractionManager_InteractionSourceUpdated(InteractionSourceUpdatedEventArgs obj)
        {
            if (obj.state.source.handedness == _handness)
            {
                if(obj.state.thumbstickPosition.magnitude > 0.2f)
                {
                    float thumbstickY = obj.state.thumbstickPosition.y;
    
                    // Vertical Input.
                    if (thumbstickY > 0.3f || thumbstickY < -0.3f)
                    {
                        _playerMovementTranslation = Camera.main.transform.forward;
                        _playerMovementTranslation.y = 0;
                        transform.Translate(_playerMovementTranslation * UserSpeed * Time.deltaTime * thumbstickY, Space.World);
                    }
                }
            }
        }
    
        /// <summary>
        /// Check that controller position is valid. 
        /// </summary>
        /// <param name="inputVector3">The Vector3 to check</param>
        /// <returns>The position is valid</returns>
        private bool ValidPosition(Vector3 inputVector3)
        {
            return !float.IsNaN(inputVector3.x) && !float.IsNaN(inputVector3.y) && !float.IsNaN(inputVector3.z) && !float.IsInfinity(inputVector3.x) && !float.IsInfinity(inputVector3.y) && !float.IsInfinity(inputVector3.z);
        }
    
        /// <summary>
        /// Check that controller rotation is valid. 
        /// </summary>
        /// <param name="inputQuaternion">The Quaternion to check</param>
        /// <returns>The rotation is valid</returns>
        private bool ValidRotation(Quaternion inputQuaternion)
        {
            return !float.IsNaN(inputQuaternion.x) && !float.IsNaN(inputQuaternion.y) && !float.IsNaN(inputQuaternion.z) && !float.IsNaN(inputQuaternion.w) && !float.IsInfinity(inputQuaternion.x) && !float.IsInfinity(inputQuaternion.y) && !float.IsInfinity(inputQuaternion.z) && !float.IsInfinity(inputQuaternion.w);
        }   
    
  6. Lägg slutligen till metodanropet i metoden Update().

        // Update is called once per frame
        void Update()
        {
            UpdateControllerState();
        }
    
  7. Se till att spara ändringarna i Visual Studio innan du återvänder till Unity.

Kapitel 11 – Konfigurera skriptreferenser

I det här kapitlet måste du placera rörelseskriptetkameraparentesen och ange dess referensmål. Skriptet hanterar sedan att placera de andra skripten där de behöver vara.

  1. Dra rörelseskriptet till objektet Kamera överordnat i hierarkipanelen från mappen Skript i projektpanelen.

    Skärmbild av panelerna Projekt och Hierarki. Rörelse är markerad.

  2. Klicka på Kamera överordnad. I hierarkipanelen drar du objektet Höger från hierarkipanelen till referensmålet Controllerkontrollpanelen. Ange användarhastigheten till 5, enligt bilden nedan.

    Skärmbild som visar panelerna Hierarki och Kontroll. En linje ansluter höger hand på båda panelerna.

Kapitel 12 – Skapa Unity-projektet

Allt som behövs för Unity-avsnittet i det här projektet har nu slutförts, så det är dags att bygga det från Unity.

  1. Gå till Build Settings (File>Build Settings).

  2. I fönstret Build Settings (Skapa inställningar ) klickar du på Skapa.

    Skärmbild av fönstret Build Settings (Skapa inställningar) som visar scener i build.

  3. Ett Utforskaren fönster visas och du uppmanas att ange en plats för bygget. Skapa en ny mapp (genom att klicka på Ny mapp i det övre vänstra hörnet) och ge den namnet BUILDS.

    Skärmbild av Utforskaren som visar mappen Builds markerad.

    1. Öppna den nya BUILDS-mappen och skapa en annan mapp (med ny mapp igen) och ge den namnet MR_Azure_Application_Insights.

      Skärmbild av Utforskaren som visar mappen MR_Azure_Insights.

    2. När MR_Azure_Application_Insights mapp är markerad klickar du på Välj mapp. Det tar ungefär en minut att skapa projektet.

  4. Efter Build visas Utforskaren som visar platsen för det nya projektet.

Kapitel 13 – Distribuera MR_Azure_Application_Insights app till din dator

Så här distribuerar du MR_Azure_Application_Insights-appen på din lokala dator:

  1. Öppna lösningsfilen för din MR_Azure_Application_Insights-app i Visual Studio.

  2. I Lösningsplattform väljer du x86, Lokal dator.

  3. I Lösningskonfiguration väljer du Felsök.

    Skärmbild av skärmen Konfiguration av Visual Studio-lösning som visar Felsökning i menyraden.

  4. Gå till menyn Skapa och klicka på Distribuera lösning för att separat läsa in programmet på datorn.

  5. Din app bör nu visas i listan över installerade appar som är redo att startas.

  6. Starta mixed reality-programmet.

  7. Flytta runt i scenen, närma dig objekt och titta på dem, när Azure Insight Service har samlat in tillräckligt med händelsedata, kommer det att ange det objekt som har kontaktats mest till grönt.

Viktigt

Den genomsnittliga väntetiden för händelser och mått som ska samlas in av tjänsten tar cirka 15 minuter, men i vissa fall kan det ta upp till 1 timme.

Kapitel 14 – Application Insights-tjänstportalen

När du har vandrat runt i scenen och tittat på flera objekt kan du se de data som samlas in i Application Insights Service-portalen .

  1. Gå tillbaka till Application Insights Service-portalen.

  2. Välj Metrics Explorer.

    Skärmbild av panelen MyNewInsight som visar listan med alternativ. Metrics Explorer visas i avsnittet Undersök.

  3. Den öppnas på en flik som innehåller grafen, som representerar händelser och mått som är relaterade till ditt program. Som nämnts ovan kan det ta en stund (upp till 1 timme) innan data visas i diagrammet

    Skärmbild av Metrics Explorer som visar diagrammet händelser och mått.

  4. Välj fältet Händelser i Total of Events by Application Version ( Totalt antal händelser efter programversion) för att se en detaljerad uppdelning av händelserna med deras namn.

    Skärmbild av sökpanelen som visar resultatet av ett anpassat händelsefilter.

Ditt program för Application Insights-tjänsten har slutförts

Grattis, du har skapat en mixed reality-app som använder Application Insights Service för att övervaka användarens aktivitet i din app.

Välkomstskärm för kurs.

Bonusövningar

Övning 1

Prova att skapa objekten ObjectInScene i stället för att skapa objekten manuellt och ange deras koordinater på planet i skripten. På så sätt kan du fråga Azure vad det mest populära objektet var (antingen från blick eller närhetsresultat) och skapa ett extra objekt.

Övning 2

Sortera dina Application Insights-resultat efter tid, så att du får de mest relevanta data och implementerar tidskänsliga data i ditt program.