HoloLens (1. generációs) és Az Azure 309: Application Insights

Megjegyzés

A Mixed Reality Academy oktatóanyagait HoloLens (1. generációs) és Mixed Reality modern headsetekkel tervezték. Ezért fontosnak tartjuk, hogy ezeket az oktatóanyagokat helyben hagyjuk azoknak a fejlesztőknek, akik még mindig útmutatást keresnek az ilyen eszközök fejlesztéséhez. Ezek az oktatóanyagok nem frissülnek a HoloLens 2-höz használt legújabb eszközkészletekkel vagy interakciókkal. A támogatott eszközökön továbbra is működni fognak. A jövőben egy új oktatóanyag-sorozat lesz közzétéve, amely bemutatja, hogyan fejleszthet a HoloLens 2-es verziójára. Ez az értesítés frissülni fog az oktatóanyagokra mutató hivatkozással a közzétételükkor.

The Mixed Reality Academy tutorial welcome screen.

Ebben a kurzusban megtudhatja, hogyan adhat alkalmazás-Elemzések képességeket egy vegyes valósági alkalmazáshoz a Azure-alkalmazás Elemzések API használatával a felhasználói viselkedéssel kapcsolatos elemzések gyűjtéséhez.

Az alkalmazás-Elemzések egy Microsoft-szolgáltatás, amely lehetővé teszi a fejlesztők számára, hogy elemzéseket gyűjtsenek az alkalmazásaikból, és egy könnyen használható portálról kezeljék azt. Az elemzés bármilyen lehet a teljesítménytől kezdve az összegyűjteni kívánt egyéni információkig. További információért látogasson el az Alkalmazás Elemzések oldalra.

A tanfolyam elvégzése után egy vegyes valósági modern headset alkalmazással fog rendelkezni, amely a következőket teszi:

  1. Lehetővé teszi, hogy a felhasználó megtekintse és mozogjon egy jelenetben.
  2. Aktiválja az elemzések küldését az Application Elemzések Service-be a Tekintet és közelség funkcióval a jeleneten belüli objektumokhoz.
  3. Az alkalmazás meghívja a Szolgáltatást is, és beolvassa az adatokat arról, hogy melyik objektumot közelítette meg a felhasználó a legtöbbet az elmúlt 24 órában. Az objektum színe zöldre változik.

Ez a tanfolyam bemutatja, hogyan szerezheti be az eredményeket az Application Elemzések Service-ből egy Unity-alapú mintaalkalmazásba. Ezeket a fogalmakat ön fogja alkalmazni egy egyéni alkalmazásra, amely lehet, hogy létrejön.

Eszköztámogatás

Tanfolyam HoloLens Modern headsetek
MR és Azure 309: Application Insights ✔️ ✔️

Megjegyzés

Bár ez a tanfolyam elsősorban Windows Mixed Reality modern (VR) headsetekre összpontosít, a tanfolyamban tanultakat alkalmazhatja Microsoft HoloLens. Ahogy követi a tanfolyamot, jegyzeteket fog látni a HoloLens támogatásához esetleg szükséges módosításokról. A HoloLens használatakor visszhangot tapasztalhat a hangrögzítés során.

Előfeltételek

Megjegyzés

Ez az oktatóanyag olyan fejlesztők számára készült, akik alapszintű tapasztalattal rendelkeznek a Unity és a C# terén. Felhívjuk a figyelmét arra is, hogy a jelen dokumentumban foglalt előfeltételek és írásos utasítások azt írják le, amit az íráskor (2018. július) teszteltek és ellenőriztek. Szabadon használhatja a legújabb szoftvert, ahogy az a telepítési cikkben szerepel, bár nem szabad feltételezni, hogy az ebben a kurzusban szereplő információk tökéletesen megfelelnek az újabb szoftverekben található információknak, mint az alább felsoroltak.

Ehhez a tanfolyamhoz a következő hardvereket és szoftvereket javasoljuk:

Előkészületek

A projekt létrehozásakor felmerülő problémák elkerülése érdekében javasoljuk, hogy ebben az oktatóanyagban a projektet gyökérszintű vagy gyökérszintű mappában hozza létre (a hosszú mappaelérési utak problémákat okozhatnak a buildelés során).

Figyelmeztetés

Vegye figyelembe, hogy az Alkalmazásba Elemzések adatok időt vesz igénybe, ezért legyen türelmes. Ha ellenőrizni szeretné, hogy a Szolgáltatás megkapta-e az Ön adatait, tekintse meg a 14. fejezetet, amely bemutatja, hogyan navigálhat a portálon.

1. fejezet – Az Azure Portal

Az Application Elemzések használatához létre kell hoznia és konfigurálnia kell egy application Elemzések szolgáltatást a Azure Portal.

  1. Jelentkezzen be az Azure Portal.

    Megjegyzés

    Ha még nem rendelkezik Azure-fiókkal, létre kell hoznia egyet. Ha osztályterem- vagy laborhelyzetben követi ezt az oktatóanyagot, kérjen segítséget az oktatótól vagy az egyik proktortól az új fiók beállításához.

  2. Miután bejelentkezett, kattintson a bal felső sarokban az Új gombra, keresse meg az Alkalmazás Elemzések, majd kattintson az Enter gombra.

    Megjegyzés

    Lehetséges, hogy az Új szót lecserélték erőforrás létrehozására az újabb portálokon.

    Screenshot showing the Azure Portal, Insight is highlighted in the Everything pane.

  3. A jobb oldali új oldalon megjelenik a Azure-alkalmazás Elemzések Szolgáltatás leírása. A lap bal alsó részén kattintson a Létrehozás gombra a szolgáltatással való társítás létrehozásához.

    Screenshot of the Application Insights screen, Create is highlighted.

  4. Miután a Létrehozás gombra kattintott:

    1. Adja meg a szolgáltatáspéldány kívánt nevét .

    2. Alkalmazástípusként válassza az Általános lehetőséget.

    3. Válasszon ki egy megfelelő előfizetést.

    4. Válasszon egy erőforráscsoportot , vagy hozzon létre egy újat. Az erőforráscsoportok segítségével monitorozhat, szabályozhat hozzáférést, kiépíteni és kezelni tudja az Azure-objektumok gyűjteményének számlázását. Javasoljuk, hogy az egyetlen projekthez (például ezekhez a kurzusokhoz) társított összes Azure-szolgáltatást egy közös erőforráscsoportban tartsa.

      Ha többet szeretne megtudni az Azure-erőforráscsoportokról, tekintse meg az erőforráscsoportról szóló cikket.

    5. Válasszon egy helyet.

    6. Azt is meg kell erősítenie, hogy megértette a szolgáltatásra vonatkozó feltételeket és kikötéseket.

    7. Válassza a Létrehozás lehetőséget.

      Screenshot of the Application Insights window. Name and application type are highlighted.

  5. Miután a Létrehozás gombra kattintott, meg kell várnia a szolgáltatás létrehozását, ami eltarthat egy percig.

  6. A szolgáltatáspéldány létrehozása után megjelenik egy értesítés a portálon.

    Screenshot showing a portion of the menu ribbon, the notification icon is highlighted.

  7. Válassza ki az értesítéseket az új szolgáltatáspéldány vizsgálatához.

    Screenshot showing the Deployment succeeded dialog, Go to resource is highlighted.

  8. Az értesítésben kattintson az Erőforrás megnyitása gombra az új szolgáltatáspéldány megismeréséhez. Ekkor megnyílik az új Application Elemzések Service-példány.

    Screenshot showing the Application Insights Service instance where the instance name is MyNewInsight.

    Megjegyzés

    Hagyja megnyitva ezt a weblapot, és könnyen elérhető legyen. Gyakran visszatér ide, hogy megtekintse az összegyűjtött adatokat.

    Fontos

    Az Application Elemzések implementálásához három (3) konkrét értéket kell használnia: rendszerállapotkulcsot, alkalmazásazonosítót és API-kulcsot. Az alábbiakban megtudhatja, hogyan kérdezheti le ezeket az értékeket a szolgáltatásból. Ügyeljen arra, hogy ezeket az értékeket egy üres Jegyzettömb oldalon jegyezze fel, mert hamarosan használni fogja őket a kódban.

  9. A Rendszerállapotkulcs megkereséséhez le kell görgetnie a szolgáltatásfüggvények listáját, és ki kell választania a Tulajdonságok lehetőséget. A megjelenő lapon megjelenik a szolgáltatáskulcs.

    Screenshot showing service functions, Properties is highlighted in the Configure section and Instrumentation Key is highlighted in the main pane.

  10. A Tulajdonságok területen egy kicsit lejjebb találja az API Accesst, amelyre kattintania kell. A jobb oldali panelen megadhatja az alkalmazás alkalmazásazonosítóját .

    Screenshot showing service functions, A P I Access is highlighted. Create A P I Key and Application I D are highlighted in the main pane.

  11. Ha az alkalmazásazonosító panel továbbra is nyitva van, kattintson az API-kulcs létrehozása elemre, amely megnyitja az API-kulcs létrehozása panelt.

    Screenshot showing the Create A P I key panel.

  12. A most megnyitott Api-kulcs létrehozása panelen adjon meg egy leírást, és jelölje be a három jelölőnégyzetet.

  13. Kattintson a Kulcs létrehozása gombra. Ekkor létrejön és megjelenik az API-kulcs .

    Screenshot of the Create A P I key panel showing the new service key information.

    Figyelmeztetés

    Ez az egyetlen alkalom, amikor a szolgáltatáskulcs megjelenik, ezért győződjön meg arról, hogy másolatot készít róla.

2. fejezet – A Unity-projekt létrehozása

Az alábbiakban a vegyes valósággal való fejlesztés tipikus beállítása szerepel, és mint ilyen, más projektekhez is jó sablon.

  1. Nyissa meg a Unityt , és kattintson az Új gombra.

    Screenshot of the Unity projects window. No project information is shown.

  2. Most meg kell adnia egy Unity-Project nevét, be kell szúrnia MR_Azure_Application_Insights. Győződjön meg arról, hogy a sablon3D értékre van állítva. Állítsa be a Helyet az Ön számára megfelelő helyre (ne feledje, a gyökérkönyvtárakhoz való közelebbi beállítás jobb). Ezután kattintson a Projekt létrehozása gombra.

    Screenshot of the Unity new projects window, showing project information.

  3. Ha a Unity nyitva van, érdemes ellenőrizni, hogy az alapértelmezett SzkriptszerkesztőVisual Studio van-e beállítva. Lépjen a Beállítások szerkesztése > elemre, majd az új ablakban lépjen a Külső eszközök elemre. Módosítsa a külső szkriptszerkesztőtVisual Studio 2017-re. Zárja be a Beállítások ablakot.

    Screenshot showing Visual Studio is set up as the external script editor.

  4. Ezután lépjen a Fájl > buildelési Gépház, és váltson Univerzális Windows-platform platformra a Platformváltás gombra kattintva.

    Screenshot of the Build Settings window, showing the Platform selection list. Universal Windows Platform is selected.

  5. Lépjen a Fájl > buildelési Gépház, és győződjön meg arról, hogy:

    1. A céleszközbármely eszközre van állítva

      A Microsoft HoloLens állítsa a céleszköztHoloLens értékre.

    2. A build típusaD3D értékre van állítva

    3. Az SDK a Legújabb telepítve értékre van állítva

    4. A buildelés és a futtatáshelyi gépre van állítva

    5. Mentse a jelenetet, és adja hozzá a buildhez.

      1. Ehhez válassza a Nyitott jelenetek hozzáadása lehetőséget. Ekkor megjelenik egy mentési ablak.

        Screenshot of the Build Settings window, Add Open Scenes is selected.

      2. Hozzon létre egy új mappát ehhez és bármely jövőbeli jelenethez, majd kattintson az Új mappa gombra egy új mappa létrehozásához, és adja neki a Jelenetek nevet.

        Screenshot of the Save Scene window, the Scenes folder is selected.

      3. Nyissa meg az újonnan létrehozott Jelenetek mappát, majd a Fájlnév: szövegmezőbe írja be az ApplicationInsightsScene parancsot, majd kattintson a Mentés gombra.

        Screenshot of the Save Scene window with the file name entered.

  6. A Build Gépház többi beállításának egyelőre alapértelmezettnek kell lennie.

  7. A Build Gépház ablakban válassza a Player Gépház lehetőséget. Ekkor megnyílik a kapcsolódó panel azon a helyen, ahol az Inspector található.

    Screenshot of the Inspector tab showing Player Settings.

  8. Ebben a panelen ellenőrizni kell néhány beállítást:

    1. Az Egyéb Gépház lapon:

      1. A szkriptelésifuttatókörnyezet verziójánakkísérletinek (.NET 4.6-os megfelelőnek) kell lennie, ami elindítja a szerkesztő újraindításának szükségességét.

      2. A szkriptelési háttérrendszernek.NET-nek kell lennie

      3. Az API-kompatibilitási szintnek.NET 4.6-osnak kell lennie

      Screenshot of the Inspector tab showing details in the configuration section of Other Settings.

    2. A Közzététel Gépház lap Képességek területén ellenőrizze a következőt:

      • InternetClient

        Screenshot of the Capabilities list, Internet client is checked.

    3. A panelen lejjebb, az XR Gépház (amely a Közzétételi Gépház alatt található) jelölje be a Virtual Reality támogatott jelölőnégyzetét, és győződjön meg arról, hogy a Windows Mixed Reality SDK hozzá van adva.

      Screenshot of the X R Settings section, Virtual Reality Supported is checked.

  9. A Build Gépház-ben a Unity C#-projektek már nem szürkítve jelennek meg; jelölje be a mellette lévő jelölőnégyzetet.

  10. Zárja be a Build Gépház ablakot.

  11. Mentse a jelenetet és a Project (FÁJL>MENTÉSE JELENET/FÁJL>MENTÉSE PROJEKT).

3. fejezet – A Unity-csomag importálása

Fontos

Ha ki szeretné hagyni a kurzus Unity Set up összetevőit, és közvetlenül a kódban folytatja, töltse le ezt az Azure-MR-309.unitypackage csomagot, és importálja a projektbe egyéni csomagként. Ez a következő fejezet DLL-eit is tartalmazni fogja. Az importálást követően folytassa a 6. fejezetben.

Fontos

Az Application Elemzések Unityben való használatához importálnia kell a HOZZÁ tartozó DLL-t a Newtonsoft DLL-vel együtt. A Unityben jelenleg ismert probléma áll fenn, amely megköveteli a beépülő modulok importálás utáni újrakonfigurálását. Ezekre a lépésekre (ebben a szakaszban a 4–7. lépésre) már nincs szükség a hiba megoldása után.

Az Application Elemzések saját projektbe való importálásához győződjön meg arról, hogy letöltötte a beépülő modulokat tartalmazó .unitypackage csomagot. Ezután tegye a következőket:

  1. Adja hozzá a.unitypackage** csomagot a Unityhez az Assets Import Package Custom Package (Eszközök > importálása egyéni csomag > ) menüelem használatával.

  2. A felugró Unity-csomag importálása párbeszédpanelen győződjön meg arról, hogy a beépülő modulok alatt (és azokat is beleértve) minden elem ki van jelölve.

    Screenshot of the Import Unity Package dialog box showing all items checked.

  3. Kattintson az Importálás gombra az elemek projekthez való hozzáadásához.

  4. Nyissa meg a Elemzések mappát Project nézetben a Beépülő modulok csoportban, és csak a következő beépülő modulokat válassza ki:

    • Microsoft.ApplicationInsights

    Screenshot of the Project panel, the Insights folder is open.

  5. Ezzel a beépülő modullal győződjön meg arról, hogy a Bármely platformnincs bejelölve, majd győződjön meg arról, hogy a WSAPlayer is nincs bejelölve, majd kattintson az Alkalmaz gombra. Ez csak a fájlok helyes konfigurálását erősíti meg.

    Screenshot of the Inspector panel showing Editor and Standalone checked.

    Megjegyzés

    Ha így jelöli meg a beépülő modulokat, úgy konfigurálja őket, hogy csak a Unity Editorban legyenek használva. A WSA mappában más DLL-ek találhatók, amelyeket a rendszer a projekt Unityből való exportálása után fog használni.

  6. Ezután meg kell nyitnia a WSA mappát a Elemzések mappában. Ugyanannak a fájlnak a másolatát fogja látni, amit konfigurált. Jelölje ki ezt a fájlt, majd a vizsgálóban győződjön meg arról, hogy a Bármely platformnincs bejelölve, majd győződjön meg arról, hogy csak a WSAPlayervan bejelölve. Kattintson az Alkalmaz gombra.

    Screenshot of the Inspector panel showing W S A Player checked.

  7. Most a 4–6. lépést kell követnie, de ehelyett a Newtonsoft beépülő modulokat kell használnia. Az alábbi képernyőképen láthatja, hogy hogyan kell kinéznie az eredménynek.

    Screenshot of four views of the Project and Inspector panels showing the results of setting up the Newtonsoft folder and plugin selections.

4. fejezet – A kamera és a felhasználói vezérlők beállítása

Ebben a fejezetben beállítja a kamerát és a vezérlőket, hogy a felhasználó láthassa és mozoghasson a jelenetben.

  1. Kattintson a jobb gombbal egy üres területre a Hierarchia panelen, majd válassza azÜreslétrehozása parancsot>.

    Screenshot of the Hierarchy panel, Create Empty is selected.

  2. Nevezze át az új üres GameObject objektumot Kamera Parent névre.

    Screenshot of the Hierarchy panel with Camera Parent selected. The Inspector panel

  3. Kattintson a jobb gombbal egy üres területre a Hierarchia panelen, majd a 3D objektumon, majd a Gömbön.

  4. Nevezze át a gömböt jobb kézre.

  5. A jobb kéz átalakítási skálájának beállítása 0.1, 0.1, 0.1 értékre

    Screenshot of the Hierarchy and Inspector panels, the Transform section on the Inspector panel is highlighted.

  6. Távolítsa el a Sphere ütköző összetevőt a jobb kézből a Gömbütköző összetevő fogaskerék elemére kattintva, majd távolítsa el az összetevőt.

    Screenshot of the Inspector panel, the gear icon and Remove Component are highlighted in the Sphere Collider section.

  7. A Hierarchia panelen húzza a Fő Kamera és a Jobb oldali objektumot a Kamera Szülő objektumra.

    Screenshot of the Hierarchy panel with Main Camera selected, the Inspector panel shows Main Camera checked.

  8. Állítsa a fő Kamera és a jobb oldali objektum átalakítási pozícióját0, 0, 0 értékre.

    Screenshot of the Hierarchy panel with Main Camera selected, Transform settings are highlighted in the Inspector panel.

    Screenshot of the Hierarchy panel with Right Hand selected, Transform settings are highlighted in the Inspector panel.

5. fejezet – Objektumok beállítása a Unity-jelenetben

Most létre fog hozni néhány alapvető alakzatot a jelenethez, amelyekkel a felhasználó interakcióba léphet.

  1. Kattintson a jobb gombbal egy üres területre a Hierarchia panelen, majd a 3D objektumon válassza a Sík lehetőséget.

  2. Állítsa a síkátalakítási pozíciót0, -1, 0 értékre.

  3. Állítsa a Sík átalakítása skálát5, 1, 5 értékre.

    Screenshot of the Scene, Hierarchy, and Inspector panels. The Transform section in the Inspector panel is highlighted.

  4. A Plane objektummal használható alapanyag létrehozása, hogy a többi alakzat könnyebben látható legyen. Lépjen a Project panelre, kattintson a jobb gombbal, majd kattintson a Létrehozás, majd a Mappa elemre egy új mappa létrehozásához. Adja neki az Anyagok nevet.

    Screenshot of the Project panel showing Create and Folder highlighted.Screenshot of the Project panel. Materials is highlighted in the Assets pane.

  5. Nyissa meg az Anyagok mappát, majd kattintson a jobb gombbal a Létrehozás, majd az Anyag elemre egy új anyag létrehozásához. Kéknek nevezze el.

    Screenshot of the Project panel showing Create and Material highlighted.Screenshot of the Project panel. Blue is highlighted in the Materials pane.

  6. Az új Kék anyag kijelölése után nézze meg az Inspector-t, és kattintson az Albedo melletti téglalap alakú ablakra. Válasszon egy kék színt (az alábbi képen hexadecimális szín: #3592FFFF). Miután kiválasztotta, kattintson a bezárás gombra.

    Screenshot of the Inspector panel. The color section is highlighted.

  7. Húzza az új anyagot az Anyagok mappából az újonnan létrehozott síkra a jeleneten belül (vagy helyezze a Hierarchia Sík objektumára).

    Screenshot of the Scene panel showing the new material from the Materials folder.

  8. Kattintson a jobb gombbal egy üres területre a Hierarchia panelen, majd a 3D objektumon, a Kapszulán.

    • Ha a kapszula ki van jelölve, módosítsa átalakítópozícióját a következőre: -10, 1, 0.
  9. Kattintson a jobb gombbal egy üres területre a Hierarchia panelen, majd a 3D objektumon, a Kockán.

    • Ha a kocka ki van jelölve, módosítsa átalakítópozícióját a következőre: 0, 0, 10.
  10. Kattintson a jobb gombbal egy üres területre a Hierarchia panelen, majd a 3D objektum Gömb területén.

    • Ha a gömb ki van jelölve, módosítsa a átalakításipozíciójáta következőre: 10, 0, 0.

    Screenshot of the Scene, Hierarchy, and Inspector panels. Capsule is selected in the Hierarchy panel.

    Megjegyzés

    Ezek a pozícióértékekjavaslatok. Szabadon beállíthatja az objektumok pozícióját a kívánt értékre, bár az alkalmazás felhasználója számára egyszerűbb, ha az objektumok távolsága nem túl messze van a kamerától.

  11. Ha az alkalmazás fut, képesnek kell lennie azonosítani a jeleneten belüli objektumokat, ehhez címkével kell ellátni őket. Jelölje ki az egyik objektumot, majd az Inspector panelen kattintson a Címke hozzáadása...gombra, amely felcseréli az Inspector-t a Címkék & rétegei panellel.

    Screenshot of the Inspector panel showing the Add Tag option highlighted.Screenshot of the Inspector panel showing Tags and Layers highlighted.

  12. Kattintson a + (plusz) szimbólumra, majd írja be a címke nevét ObjectInScene néven.

    Screenshot of the Inspector panel with Tags and Layers selected. The New Tag Name dialog is highlighted.

    Figyelmeztetés

    Ha más nevet használ a címkéhez, akkor gondoskodnia kell arról, hogy ez a módosítás a DataFromAnalytics, az ObjectTrigger és a Gaze szkripteket is később végezze el, hogy a rendszer megtalálja és észlelje az objektumokat a jeleneten belül.

  13. A létrehozott címkét most mind a három objektumra alkalmaznia kell. A hierarchiában tartsa lenyomva a Shift billentyűt, majd kattintson a Kapszula, Kocka és Gömb objektumok elemre, majd az Inspector eszközben kattintson a Címke melletti legördülő menüre, majd a létrehozott ObjectInScene címkére.

    Screenshot of the Inspector panel, an arrow points to Tag. The Untagged menu shows Untagged checked and ObjectInScene is selected.Screenshot showing two menus with Create and Folder highlighted.

6. fejezet – Az ApplicationInsightsTracker osztály létrehozása

Az első létrehozandó szkript az ApplicationInsightsTracker, amely a következőkért felelős:

  1. Események létrehozása a Azure-alkalmazás Elemzések elküldendő felhasználói interakciók alapján.

  2. Megfelelő eseménynevek létrehozása a felhasználói beavatkozástól függően.

  3. Események elküldése az Application Elemzések Service-példánynak.

Az osztály létrehozása:

  1. Kattintson a jobb gombbal a Project panelen, majd hozza létre> amappát. Nevezze el a mappát Szkriptek néven.

    Screenshot of the Projects panel. The Scripts folder icon is highlighted in the Assets pane.Screenshot showing menu options where the options, Create and C# Script are selected.

  2. A Szkriptek mappa létrehozása után kattintson rá duplán a megnyitásához. Ezután a mappában kattintson a jobb gombbal aC#-szkriptlétrehozása> parancsra. Adja a szkriptnek az ApplicationInsightsTracker nevet.

  3. Kattintson duplán az új ApplicationInsightsTracker szkriptre a Visual Studio megnyitásához.

  4. Frissítse a névtereket a szkript tetején, hogy az alábbiak szerint legyen:

        using Microsoft.ApplicationInsights;
        using Microsoft.ApplicationInsights.DataContracts;
        using Microsoft.ApplicationInsights.Extensibility;
        using UnityEngine;
    
  5. Az osztályon belül szúrja be a következő változókat:

        /// <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;
    

    Megjegyzés

    Állítsa be megfelelően a instrumentationKey, applicationId és API_Key értékeket az Azure Portal 1. fejezetének 9. lépésében említett szolgáltatáskulcsok használatával.

  6. Ezután adja hozzá a Start menü() és a Awake() metódusokat, amelyek az osztály inicializálásakor lesznek meghívva:

        /// <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. Adja hozzá az alkalmazás által regisztrált események és metrikák küldéséért felelős metódusokat:

        /// <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. Ne felejtse el menteni a módosításokat a Visual Studio, mielőtt visszatér a Unitybe.

7. fejezet – A Gaze szkript létrehozása

A következő létrehozandó szkript a Gaze szkript. Ez a szkript felelős egy Raycast létrehozásáért, amely előre lesz vetítve a Fő Kamera, hogy észlelje, melyik objektumot vizsgálja a felhasználó. Ebben az esetben a Raycastnak azonosítania kell, hogy a felhasználó egy ObjectInScene címkével rendelkező objektumot keres-e, majd meg kell számolnia, hogy a felhasználó mennyi ideig tekint az objektumra.

  1. Kattintson duplán a Scripts mappára a megnyitásához.

  2. Kattintson a jobb gombbal a Parancsfájlok mappába, és válassza aC#-szkriptlétrehozása> parancsot. Nevezze el a szkriptet Gaze-nak.

  3. Kattintson duplán a szkriptre a Visual Studio megnyitásához.

  4. Cserélje le a meglévő kódot a következőre:

        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. Az Awake() és a Start menü() metódus kódját most hozzá kell adni.

        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. A Gaze osztályon belül adja hozzá a következő kódot az Update() metódushoz egy Raycast kivetítéséhez és a célütközés észleléséhez:

        /// <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. Adja hozzá a ResetFocusedObject() metódust, hogy adatokat küldjön az Alkalmazás Elemzések, amikor a felhasználó megtekintett egy objektumot.

        /// <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. Ezzel befejezte a Gaze szkriptet. Mentse a módosításokat Visual Studio, mielőtt visszatér a Unitybe.

8. fejezet – Az ObjectTrigger osztály létrehozása

A következő létrehozandó szkript az ObjectTrigger, amely a következőkért felelős:

  • Összeütközéshez szükséges összetevők hozzáadása a Fő Kamera.
  • Észleli, hogy a kamera egy ObjectInScene címkével ellátott objektum közelében van-e.

A szkript létrehozása:

  1. Kattintson duplán a Scripts mappára a megnyitásához.

  2. Kattintson a jobb gombbal a Parancsfájlok mappába, és válassza aC#-szkriptlétrehozása> parancsot. Nevezze el az ObjectTrigger parancsprogramot.

  3. Kattintson duplán a szkriptre a Visual Studio megnyitásához. Cserélje le a meglévő kódot a következőre:

        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. Ne felejtse el menteni a módosításokat a Visual Studio, mielőtt visszatér a Unitybe.

9. fejezet – A DataFromAnalytics osztály létrehozása

Most létre kell hoznia a DataFromAnalytics szkriptet, amely a következőkért felelős:

  • Elemzési adatok beolvasása arról, hogy a kamera melyik objektumot közelítette meg a legjobban.
  • A szolgáltatáskulcsok használatával, amelyek lehetővé teszik a Azure-alkalmazás Elemzések Service-példánysal való kommunikációt.
  • A jelenet objektumainak rendezése, amelyek szerint a legmagasabb eseményszámmal rendelkezik.
  • A leggyakrabban használt objektum anyagszínének módosítása zöldre.

A szkript létrehozása:

  1. Kattintson duplán a Scripts mappára a megnyitásához.

  2. Kattintson a jobb gombbal a Parancsfájlok mappába, és válassza aC#-szkriptlétrehozása> parancsot. Nevezze el a DataFromAnalytics szkriptet.

  3. Kattintson duplán a szkriptre a Visual Studio megnyitásához.

  4. Szúrja be a következő névtereket:

        using Newtonsoft.Json;
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. Szúrja be a következőt a szkriptbe:

        /// <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. A DataFromAnalytics osztályban közvetlenül a Start menü() metódus után adja hozzá a következő FetchAnalytics() metódust. Ez a metódus felelős a kulcsértékpárok listájának feltöltéséért, egy GameObject és egy helyőrző eseményszám számával. Ezután inicializálja a GetWebRequest() coroutine-t. Az Application Elemzések hívásának lekérdezési struktúrája ebben a metódusban is megtalálható a lekérdezési URL-végpontként.

        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. A FetchAnalytics() metódus alatt adjon hozzá egy GetWebRequest() nevű metódust, amely egy IEnumerator értéket ad vissza. Ez a metódus felelős egy adott GameObjectnek megfelelő esemény meghívásának hányszori kéréséért az Application Elemzések. Amikor az összes elküldött lekérdezést visszaadta, a Rendszer meghívja a DetermineWinner() metódust.

        /// <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. A következő metódus a DetermineWinner(), amely a GameObject és az Int párok listáját rendezi a legmagasabb eseményszám alapján. Ezután a GameObject anyagszínét zöldre módosítja (visszajelzésként arra vonatkozóan, hogy a legmagasabb a száma). Ekkor megjelenik egy üzenet az elemzés eredményeivel.

        /// <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. Adja hozzá az osztálystruktúrát, amely az Application Elemzések-tól kapott JSON-objektum deszerializálására szolgál. Vegye fel ezeket az osztályokat a DataFromAnalytics osztályfájl alján, az osztálydefiníción kívül .

        /// <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. Ne felejtse el menteni a módosításokat a Visual Studio, mielőtt visszatér a Unitybe.

10. fejezet – A Mozgás osztály létrehozása

A movement szkript a következő szkript, amelyet létre kell hoznia. Az alábbiakért felelős:

  • A Fő Kamera mozgatása a kamera által keresett iránynak megfelelően.
  • Az összes többi szkript hozzáadása jelenetobjektumokhoz.

A szkript létrehozása:

  1. Kattintson duplán a Scripts mappára a megnyitásához.

  2. Kattintson a jobb gombbal a Parancsfájlok mappába, és válassza aC#-szkriptlétrehozása> parancsot. Nevezze el a szkript áthelyezését.

  3. Kattintson duplán a szkriptre a Visual Studio megnyitásához.

  4. Cserélje le a meglévő kódot a következőre:

        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. A Movementosztályban , az üres Update() metódus alá szúrja be a következő metódusokat, amelyek lehetővé teszik, hogy a felhasználó a kézi vezérlővel mozogjon a virtuális térben:

        /// <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. Végül adja hozzá a metódushívást az Update() metódushoz.

        // Update is called once per frame
        void Update()
        {
            UpdateControllerState();
        }
    
  7. Ne felejtse el menteni a módosításokat a Visual Studio, mielőtt visszatér a Unitybe.

11. fejezet – A szkripthivatkozások beállítása

Ebben a fejezetben a movement szkriptet a Kamera Szülőre kell helyeznie, és meg kell adnia a referenciacéljait. Ez a szkript fogja kezelni a többi szkript elhelyezését, ahol szükség van rájuk.

  1. A Project panelParancsfájlok mappájából húzza a Mozgás parancsprogramot a hierarchiapanelen található Kamera szülőobjektumba.

    Screenshot of the Project and Hierarchy panels. Movement is highlighted.

  2. Kattintson a Kamera szülőre. A Hierarchia panelen húzza a Jobb oldali objektumot a Hierarchia panelről a Vezérlő hivatkozási célhoz a Vizsgáló panelen. Állítsa a felhasználói sebességet5-ösre az alábbi képen látható módon.

    Screenshot showing the Hierarchy and Inspector panels. A line connects Right Hand on both panels.

12. fejezet – A Unity-projekt létrehozása

A projekt Unity szakaszához szükséges összes elem elkészült, ezért itt az ideje, hogy buildeljük a Unityből.

  1. Lépjen a Build Gépház (Fájl>buildelési Gépház) lapra.

  2. A Build Gépház ablakban kattintson a Build elemre.

    Screenshot of the Build Settings window showing Scenes In Build.

  3. Ekkor megjelenik egy Fájlkezelő ablak, amely a build helyének megadását kéri. Hozzon létre egy új mappát (a bal felső sarokban az Új mappára kattintva), és adja neki a BUILDS nevet.

    Screenshot of File Explorer showing the Builds folder highlighted.

    1. Nyissa meg az új BUILDS mappát, és hozzon létre egy másik mappát (még egyszer az Új mappa használatával), és nevezze el MR_Azure_Application_Insights.

      Screenshot of File explorer showing the MR_Azure_Insights folder.

    2. Jelölje ki a MR_Azure_Application_Insights mappát, és kattintson a Mappa kijelölése gombra. A projekt felépítése körülbelül egy percet vesz igénybe.

  4. A buildelés után Fájlkezelő jelenik meg az új projekt helyével.

13. fejezet – MR_Azure_Application_Insights alkalmazás üzembe helyezése a gépen

A MR_Azure_Application_Insights alkalmazás üzembe helyezése a helyi gépen:

  1. Nyissa meg a MR_Azure_Application_Insights alkalmazás megoldásfájlját Visual Studio.

  2. A Megoldásplatformon válassza az x86, Helyi gép lehetőséget.

  3. A Megoldáskonfigurációban válassza a Hibakeresés lehetőséget.

    Screenshot of the the Visual Studio Solution Configuration screen showing Debug in the menu bar.

  4. Nyissa meg a Build menüt , és kattintson a Megoldás üzembe helyezése elemre az alkalmazás gépre való közvetlen betöltéséhez.

  5. Az alkalmazásnak most már meg kell jelennie a telepített alkalmazások listájában, készen áll az indításra.

  6. Indítsa el a vegyes valóság alkalmazást.

  7. Mozoghat a jelenet körül, megközelítheti az objektumokat, és megnézheti őket, amikor az Azure Insight Service elegendő eseményadatot gyűjtött, a leginkább megközelített objektumot zöldre állítja.

Fontos

Bár a Szolgáltatás által összegyűjtendő események és metrikák átlagos várakozási ideje körülbelül 15 percet vesz igénybe, bizonyos esetekben akár 1 órát is igénybe vehet.

14. fejezet – Az alkalmazás Elemzések szolgáltatás portálja

Miután körbejárta a jelenetet, és több objektumot tekintett meg, láthatja a gyűjtött adatokat az Application Elemzések Service portálon.

  1. Vissza az Application Elemzések Service portálra.

  2. Válassza a Metrikaböngésző lehetőséget.

    Screenshot of the MyNewInsight panel showing the list of options. Metrics Explorer is listed in the Investigate section.

  3. Megnyílik egy gráfot tartalmazó lapon, amely az alkalmazáshoz kapcsolódó eseményeket és metrikákat jelöli. Ahogy fentebb említettük, eltarthat egy ideig (akár 1 óráig) ahhoz, hogy az adatok megjelenjenek a gráfban

    Screenshot of the Metrics Explorer showing the events and metrics graph.

  4. Válassza az Események összesen alkalmazásverzió szerint sávot az események részletes lebontásának megtekintéséhez a nevükkel.

    Screenshot of the Search panel showing the results of a custom event filter.

Az alkalmazás Elemzések szolgáltatásalkalmazás befejezése

Gratulálunk, létrehozott egy vegyes valósági alkalmazást, amely az Application Elemzések Service használatával figyeli a felhasználó tevékenységét az alkalmazásban.

Course welcome screen.

Bónusz gyakorlatok

1. gyakorlat

Ahelyett, hogy manuálisan hozná létre az ObjectInScene objektumokat, próbálkozzon az ívással, és állítsa be a koordinátáikat a síkon a szkripteken belül. Ily módon megkérdezheti az Azure-tól, hogy mi volt a legnépszerűbb objektum (tekintetből vagy közelségi eredményekből), és további egy ilyen objektumot hozhat létre.

2. gyakorlat

Rendezze az alkalmazás Elemzések eredményeket idő szerint, hogy a legrelevánsabb adatokat kapja meg, és implementálja az időérzékeny adatokat az alkalmazásban.