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

Megjegyzés

A Mixed Reality Academy oktatóanyagait a HoloLens (1. generációs) és Mixed Reality modern headsetekkel tervezték. Ezért fontosnak tartjuk, hogy ezeket az oktatóanyagokat megtartsuk azoknak a fejlesztőknek, akik továbbra is útmutatást keresnek az eszközök fejlesztéséhez. Ezek az oktatóanyagok nem frissülnek az HoloLens 2 legújabb eszközkészleteivel vagy interakcióival. A támogatott eszközökön való munka folytatásához megmaradnak. A jövőben egy új oktatóanyag-sorozat jelenik meg, amely bemutatja, hogyan fejleszthet HoloLens 2. Ezt az értesítést a közzétételükkor az oktatóanyagokra mutató hivatkozással frissítjük.

Az Mixed Reality Academy oktatóanyag üdvözlőképernyője.

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

Az Application Insights 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ések a teljesítménytől kezdve az összegyűjteni kívánt egyéni információkig bármi lehetnek. További információt az Application Insights oldalán talál.

A tanfolyam elvégzése után vegyes valóságú, magával ragadó headset-alkalmazással rendelkezik, amely a következőket fogja tudni elvégezni:

  1. Engedélyezze a felhasználónak, hogy megtekintse és mozogjon egy jelenetben.
  2. Aktiválja az elemzések Küldését az Application Insights Szolgáltatásba a Tekintet és közelség funkcióval a helyszíni 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 leggyakrabban az elmúlt 24 órában. Az objektum színe zöldre változik.

Ez a kurzus bemutatja, hogyan szerezheti be az eredményeket az Application Insights Service-ből egy Unity-alapú mintaalkalmazásba. Ön fogja alkalmazni ezeket a fogalmakat egy egyéni alkalmazásra, amely esetleg létrejön.

Eszköztámogatás

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

Megjegyzés

Bár ez a kurzus elsősorban Windows Mixed Reality magával ragadó (VR) headsetekkel foglalkozik, a tanfolyam során tanultakat a Microsoft HoloLens is alkalmazhatja. Ahogy a tanfolyamot is követi, a HoloLens támogatásához esetleg szükséges módosításokkal kapcsolatos megjegyzéseket fog látni. A HoloLens használatakor a hangrögzítés során némi visszhangot tapasztalhat.

Előfeltételek

Megjegyzés

Ez az oktatóanyag olyan fejlesztőknek készült, akik alapszintű tapasztalattal rendelkeznek a Unityben és a C#-ben. Felhívjuk a figyelmét arra is, hogy a jelen dokumentumban foglalt előfeltételek és írásos utasítások azt felelnek meg, amit az íráskor (2018. július) teszteltek és ellenőriztek. Szabadon használhatja a legújabb szoftvert, ahogy az az eszközök telepítéséről szóló cikkben szerepel, bár nem szabad feltételezni, hogy a tanfolyam információi tökéletesen megfelelnek az újabb szoftverekben található információknak, mint az alább felsoroltak.

A tanfolyamhoz a következő hardvereket és szoftvereket ajánljuk:

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 hozzon létre egy projektet egy gyökér- vagy gyökérmappában (a hosszú mappaútvonalak buildeléskor problémákat okozhatnak).

Figyelmeztetés

Vegye figyelembe, hogy az Application Insightsba történő adatáttekintés időt vesz igénybe, ezért legyen türelmes. Ha ellenőrizni szeretné, hogy a szolgáltatás megkapta-e az adatokat, tekintse meg a 14. fejezetet, amely bemutatja, hogyan navigálhat a portálon.

1. fejezet – Az Azure Portal

Az Application Insights használatához létre kell hoznia és konfigurálnia kell egy Application Insights-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 ezt az oktatóanyagot osztályteremben vagy laborhelyzetben követi, 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 az Új gombra a bal felső sarokban, és keressen rá az Application Insights kifejezésre, majd kattintson az Enter gombra.

    Megjegyzés

    Előfordulhat, hogy az Új szót lecserélték az Erőforrás létrehozása elemre az újabb portálokon.

    Képernyőkép az Azure Portalról, az Elemzés elem ki van emelve a Minden panelen.

  3. A jobb oldalon található új oldal a Azure-alkalmazás Insights szolgáltatás leírását adja meg. A lap bal alsó sarkában kattintson a Létrehozás gombra, és hozzon létre társításokat ezzel a szolgáltatással.

    Képernyőkép az Application Insights képernyőről, a Létrehozás elem ki van emelve.

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

    1. Szúrja be a kívánt nevet ehhez a szolgáltatáspéldányhoz.

    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 lehetővé teszi az Azure-eszközök gyűjteményéhez tartozó számlázás monitorozását, vezérlését, kiépítését és kezelését. Javasoljuk, hogy az egyetlen projekthez társított összes Azure-szolgáltatást (például ezeket a kurzusokat) 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.

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

      Képernyőkép az Application Insights ablakról. A név és az alkalmazás típusa ki van emelve.

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

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

    Képernyőkép a menü menüszalagjának egy részéről, az értesítés ikonja ki van emelve.

  7. Válassza ki az értesítéseket az új szolgáltatáspéldány megismeréséhez.

    Képernyőkép a Sikeres üzembe helyezés párbeszédpanelről, az Erőforrás megnyitása ki van emelve.

  8. Az értesítésben kattintson az Erőforrás megnyitása gombra az új szolgáltatáspéldány megismeréséhez. A rendszer az új Application Insights Service-példányra viszi.

    Képernyőkép az Application Insights Service-példányról, ahol a példány neve MyNewInsight.

    Megjegyzés

    Tartsa nyitva ezt a weblapot, és könnyen elérhető legyen, gyakran visszatér ide, hogy láthassa az összegyűjtött adatokat.

    Fontos

    Az Application Insights implementálásához három (3) konkrét értéket kell használnia: Rendszerállapotkulcs, alkalmazásazonosító és API-kulcs. Az alábbiakban láthatja, hogyan lehet lekérni ezeket az értékeket a szolgáltatásból. Ügyeljen arra, hogy ezeket az értékeket egy üres Jegyzettömb lapon 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 a Tulajdonságok lehetőséget kell választania, a megjelenő lapon megjelenik a szolgáltatáskulcs.

    A szolgáltatásfüggvényeket bemutató képernyőkép, a Tulajdonságok elem ki van emelve a Konfigurálás szakaszban, a Rendszerállapotkulcs pedig ki van emelve a fő panelen.

  10. A Tulajdonságok alatt egy kicsit megtalálja az API Accesst, amelyre kattintania kell. A jobb oldali panelen megjelenik az alkalmazás alkalmazásazonosítója .

    A szolgáltatásfüggvényeket bemutató képernyőkép: A P I Access ki van emelve. A P I-kulcs létrehozása és az I D alkalmazás ki van emelve a fő panelen.

  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.

    Képernyőkép a P I-kulcs létrehozása panelről.

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

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

    Képernyőkép a P I-kulcs létrehozása panelről, amelyen az új szolgáltatáskulcs-információk láthatók.

    Figyelmeztetés

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

2. fejezet – A Unity-projekt beállítása

Az alábbiak egy tipikus beállítás a vegyes valósággal való fejlesztéshez, és mint ilyen, jó sablon más projektekhez.

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

    Képernyőkép a Unity-projektek ablakáról. Nem jelennek meg projektinformációk.

  2. Most meg kell adnia a Unity-projekt 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 a Hely értékét az Ön számára megfelelő helyre (ne feledje, a gyökérkönyvtárakhoz való közelebb jobb). Ezután kattintson a Projekt létrehozása elemre.

    Képernyőkép a Unity új projektek ablakáról, amelyen a projektinformációk láthatók.

  3. Ha a Unity nyitva van, érdemes ellenőrizni, hogy az alapértelmezett szkriptszerkesztőVisual Studióra van-e állítva. Lépjen a Beállítások szerkesztése > elemre, majd az új ablakból 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.

    Képernyőkép arról, hogy a Visual Studio külső szkriptszerkesztőként van beállítva.

  4. Ezután lépjen a Fájlkészítési > beállítások területre, és váltson a platformra Univerzális Windows-platform, és kattintson a Platformváltás gombra.

    Képernyőkép a Build Settings (Létrehozási beállítások) ablakról, amelyen a Platform kiválasztása lista látható. Univerzális Windows-platform van kiválasztva.

  5. Lépjen a Fájl > buildelési beállításai területre , és győződjön meg arról, hogy:

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

      A Microsoft HoloLens állítsa a Céleszköz értékét HoloLens értékre.

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

    3. Az SDK a Legújabb telepített é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.

        Képernyőkép a Build Settings (Létrehozási beállítások) ablakról, a Megnyitási jelenetek hozzáadása lehetőség van kiválasztva.

      2. Hozzon létre egy új mappát ehhez, és minden jövőbeli jelenethez, majd az Új mappa gombra kattintva hozzon létre egy új mappát, és adja neki a Jelenetek nevet.

        Képernyőkép a Jelenet mentése ablakról, a Jelenetek mappa ki van jelölve.

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

        Képernyőkép a Jelenet mentése ablakról a megadott fájlnévvel.

  6. A buildbeállításokban lévő többi beállításnak egyelőre alapértelmezettnek kell lennie.

  7. A Build Settings (Összeállítási beállítások ) ablakban válassza a Player Settings (Lejátszóbeállítások) lehetőséget, ezzel megnyitja a kapcsolódó panelt abban a térben, ahol az Inspector található.

    Képernyőkép az Inspector lapról, amelyen a Lejátszó beállításai látható.

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

    1. Az Egyéb beállítások lapon:

      1. A szkriptelésifuttatókörnyezet verziójánakkísérletinek (.NET 4.6-os egyenértékű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

      Képernyőkép az Inspector lapról, amelyen az Egyéb beállítások konfigurációs szakasza látható.

    2. A Közzétételi beállítások lapon, a Képességek területen ellenőrizze a következőt:

      • InternetClient

        Képernyőkép a Képességek listáról, az internetes ügyfél be van jelölve.

    3. A panelen lejjebb, az XR-beállítások területen (amely a Közzétételi beállítások alatt található) jelölje be a Virtual Reality Támogatott jelölőnégyzetet, és győződjön meg arról, hogy a Windows Mixed Reality SDK hozzá van adva.

      Képernyőkép az X R-beállítások szakaszról, a Virtual Reality támogatott jelölőnégyzete be van jelölve.

  9. A Buildbeállítások területen a Unity C#-projektek már nem szürkén jelennek meg; jelölje be a mellette lévő jelölőnégyzetet.

  10. Zárja be a Létrehozási beállítások ablakot.

  11. Mentse a jelenetet és a projektet (FILE>SAVE SCENE /FILE>SAVE PROJECT).

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ódba szeretne lépni, nyugodtan töltse le ezt az Azure-MR-309.unitypackage csomagot, importálja azt a projektbe egyéni csomagként. Ez a következő fejezetben szereplő DLL-eket is tartalmazza. Az importálás után folytassa a 6. fejezetből.

Fontos

Az Application Insights Unityben való használatához importálnia kell a DLL-t a Newtonsoft DLL-vel együtt. Jelenleg egy ismert probléma van a Unityben, 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 Insights 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** elemet a Unityhez az Eszközök > importálása csomag > egyéni csomag menüjének beállításával.

  2. Az Előugró Unity-csomag importálása mezőben győződjön meg arról, hogy a beépülő modulok alatt (és azokat is beleértve) minden ki van jelölve.

    Képernyőkép a Unity-csomag importálása párbeszédpanelről, amelyen az összes elem be van jelölve.

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

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

    • Microsoft.ApplicationInsights

    Képernyőkép a Projekt panelről, az Insights mappa meg van nyitva.

  5. Ha bejelöli ezt a beépülő modult , 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 bejelölve van, majd kattintson az Alkalmaz gombra. Ezzel csak azt szeretné ellenőrizni, hogy a fájlok megfelelően vannak-e konfigurálva.

    Képernyőkép az Inspector panelről, amelyen a Szerkesztő és az Önálló elem be van jelölve.

    Megjegyzés

    A beépülő modulok így való megjelölésével úgy konfigurálja őket, hogy csak a Unity-szerkesztőben használják őket. A WSA mappában különböző 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 az Insights mappában. Ugyanannak a fájlnak a másolatát fogja látni, amit konfigurált. Jelölje ki ezt a fájlt, majd az ellenőrben győződjön meg arról, hogy a Bármely platformnincs bejelölve, majd győződjön meg arról, hogy csaka WSAPlayervan bejelölve. Kattintson az Alkalmaz gombra.

    Képernyőkép az Inspector panelről, amelyen a W S A Player be van jelölve.

  7. Most már a 4-6. lépést kell követnie, de ehelyett a Newtonsoft beépülő modulokat. Tekintse meg az alábbi képernyőképet arról, hogy az eredménynek milyennek kell lennie.

    Képernyőkép a Project és az Inspector panel négy nézetéről, amelyek a Newtonsoft mappa beállításának és a beépülő modul kiválasztásának eredményeit mutatják.

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 azÜreslétrehozása> parancsra.

    Képernyőkép a Hierarchia panelről, a Create Empty (Üres létrehozása) lehetőség van kiválasztva.

  2. Nevezze át az új üres GameObject nevet a Kamera szülője névre.

    Képernyőkép a Hierarchia panelről, amelyen a Kamera szülője van kijelölve. Az 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. Állítsa a jobb oldali skálázási skálát0,1, 0,1, 0,1 értékre

    Képernyőkép a Hierarchia és az Inspector panelről, az Inspector panel Átalakítás szakasza ki van emelve.

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

    Képernyőkép az Inspector panelről, a fogaskerék ikon és az Összetevő eltávolítása a Sphere Collider szakaszban.

  7. A Hierarchia panelen húzza a fő kamerát és a jobb oldali objektumot a Kamera szülőobjektumára .

    Képernyőkép a Hierarchia panelről, amelyen a Fő kamera van kiválasztva, az Inspector panelen a Fő kamera van bejelölve.

  8. Állítsa a fő kamera és a jobb oldali objektum 0, 0, 0transzformációs pozícióját.

    Képernyőkép a Hierarchia panelről, amelyen a Fő kamera van kiválasztva, az Átalakítás beállításai ki vannak emelve az Inspector panelen.

    Képernyőkép a Hierarchia panelről, amelyen a Jobb kéz van kijelölve, az Átalakítás beállításai ki vannak emelve az Inspector panelen.

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, majd válassza a Sík lehetőséget.

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

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

    Képernyőkép a Jelenet, a Hierarchia és az Inspector panelről. Az Inspector panel Átalakítás szakasza ki van emelve.

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

    Képernyőkép a Projekt panelről, amelyen a Létrehozás és a Mappa elem van kiemelve.Képernyőkép a Projekt panelről. Az Anyagok elem ki van emelve az Eszközök panelen.

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

    Képernyőkép a Projekt panelről, amelyen a Létrehozás és az Anyag elem van kiemelve.Képernyőkép a Projekt panelről. A Kék elem ki van emelve az Anyagok panelen.

  6. Az új Kék anyag kiválasztásával nézze meg az Inspector-t, és kattintson a téglalap alakú ablakra az Albedo mellett. Válasszon egy kék színt (az alábbi képen a Hexadecimális szín: #3592FFFF). Kattintson a bezárás gombra, miután kiválasztotta.

    Képernyőkép az Inspector panelről. A színszakasz ki van emelve.

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

    Képernyőkép a Jelenet panelről, amelyen az Anyagok mappa új anyaga látható.

  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 az átalakításpozí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 objektum, kocka területen.

    • Ha a kocka ki van jelölve, módosítsa átalakításipozí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 elemére.

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

    Képernyőkép a Jelenet, a Hierarchia és az Inspector panelről. A kapszulát a Hierarchia panelen választhatja ki.

    Megjegyzés

    Ezek a Pozíció értékek javaslatok. Szabadon beállíthatja az objektumok pozícióját tetszőlegesre, 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. Amikor az alkalmazás fut, képesnek kell lennie a jeleneten belüli objektumok azonosítására, ennek eléréséhez címkével kell ellátni őket. Jelölje ki az egyik objektumot, és az Inspector panelen kattintson a Címke hozzáadása... elemre, amely felcseréli az Inspector-t a Címkék & Rétegek panelre.

    Képernyőkép az Inspector panelről, amelyen a Címke hozzáadása lehetőség van kiemelve.Képernyőkép az Inspector panelről, amelyen a Címkék és a Rétegek elem van kiemelve.

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

    Képernyőkép az Inspector panelről, amelyen a Címkék és rétegek elem van kijelölve. Az Új címke neve párbeszédpanel ki van emelve.

    Figyelmeztetés

    Ha más nevet használ a címkéhez, gondoskodnia kell arról, hogy ez a módosítás a DataFromAnalytics, az ObjectTrigger és a Gaze szkripteket is módosítsa később, hogy az objektumok megtalálhatók és észlelhetők legyenek a jeleneten belül.

  13. Miután létrehozta a címkét, mind a három objektumra alkalmaznia kell. A hierarchiában tartsa lenyomva a Shift billentyűt, majd kattintson a Kapszula, a Kocka és a Gömb objektumra, majd az Inspector területen kattintson a legördülő menüre a Címke mellett, majd kattintson a létrehozott ObjectInScene címkére.

    Képernyőkép az Inspector panelről, egy nyíl mutat a Címke elemre. A Címkézés nélküli menüben a Megjelölés nélkül jelölőnégyzet látható, és az ObjectInScene ki van jelölve.Képernyőkép két menüről, kiemelt Létrehozás és Mappa lehetőséggel.

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. Az Azure-alkalmazás Insights szolgáltatásba küldendő felhasználói interakciókon alapuló események létrehozása.

  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 Insights Service-példánynak.

Az osztály létrehozása:

  1. Kattintson a jobb gombbal a Projekt panelen, majd válassza aMappalétrehozása parancsot>. Nevezze el a mappát Szkriptek néven.

    Képernyőkép a Projektek panelről. A Scripts mappa ikonja ki van emelve az Eszközök panelen.Képernyőkép a menü beállításairól, ahol a Létrehozás és a C# szkript lehetőség van kiválasztva.

  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 aCreate C# Script (C#-szkriptlétrehozása>) elemre. Adja a szkriptnek az ApplicationInsightsTracker nevet.

  3. Kattintson duplán az új ApplicationInsightsTracker-szkriptre a Visual Studióval való 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 szolgáltatáskulcsainak használatával az 1. fejezet 9. lépésében leírtak szerint.

  6. Ezután adja hozzá a Start() és a Awake() metódust, amely a osztály inicializálásakor lesz 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 Studióban , mielőtt visszatér a Unitybe.

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

A következő létrehozandó szkript a Gaze szkript. Ez a szkript felelős azért, hogy létrehoz egy Raycast-et , amelyet előre vetít a fő kameráról, hogy észlelje, hogy a felhasználó melyik objektumot vizsgálja. 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 Szkriptek mappára a megnyitásához.

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

  3. Kattintson duplán a szkriptre a Visual Studióval való 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() 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 a Raycast kivetítéséhez és a célütem é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 Application Insightsnak , amikor a felhasználó megvizsgált 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 a Visual Studióban , 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ő kamerához.
  • É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 Szkriptek mappára a megnyitásához.

  2. Kattintson a jobb gombbal a Szkriptek mappába, és válassza aC#-szkriptlétrehozása> parancsot. Adja a szkriptnek az ObjectTrigger nevet.

  3. Kattintson duplán a szkriptre a Visual Studióval való 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 Studióban , 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álata, amelyek lehetővé teszik a kommunikációt a Azure-alkalmazás Insights szolgáltatáspéldányával.
  • A jelenetben lévő objektumok rendezése, amelyek szerint a legmagasabb eseményszámmal rendelkezik.
  • A leggyakrabban megközelített objektum anyagszínének módosítása zöldre.

A szkript létrehozása:

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

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

  3. Kattintson duplán a szkriptre a Visual Studióval való 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. A szkriptbe szúrja be a következőt:

        /// <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() metódus után adja hozzá a következő , FetchAnalytics() nevű metódust. Ez a módszer felelős a kulcsértékpárok listájának feltöltéséért GameObject és helyőrző eseményszám számmal. Ezután inicializálja a GetWebRequest() koroutint. Az Application Insights hívásának lekérdezési struktúrája ebben a metódusban is megtalálható a Lekérdezés URL-végpontjaké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 IEnumeratort ad vissza. Ez a metódus felel egy adott GameObject-nek megfelelő esemény meghívásának hányszor az Application Insightsban. Amikor az összes elküldött lekérdezés vissza lett adva, a DeterminWinner() metódus lesz meghívva.

        /// <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 DeterminWinner(), amely a GameObject és az Int párok listáját a legmagasabb eseményszám szerint rendezi. Ezután a GameObject anyagszínét zöldre módosítja (visszajelzésként, hogy a legnagyobb számban jelenik meg). Ez egy üzenetet jelenít meg az elemzési eredményekről.

        /// <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 Application Insightstól kapott JSON-objektum deszerializálásához használt osztálystruktúrát. 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. Mielőtt visszatér a Unitybe, mentse a módosításokat a Visual Studióban.

10. fejezet – A mozgásosztály létrehozása

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

  • A fő kamera mozgatása a kamera irányának megfelelően.
  • Az összes többi szkript hozzáadása jelenetobjektumokhoz.

A szkript létrehozása:

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

  2. Kattintson a jobb gombbal a Szkriptek mappába, majd kattintson aC# szkriptlétrehozása> parancsra. Nevezze el a szkript áthelyezését.

  3. Kattintson duplán a szkriptre a Visual Studióval való 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 Mozgásosztályon belül, az üres Update() metódus alá szúrja be a következő metódusokat, amelyek lehetővé teszik a felhasználó számára, hogy 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. Mielőtt visszatér a Unitybe, mentse a módosításokat a Visual Studióban.

11. fejezet – Szkripthivatkozások beállítása

Ebben a fejezetben a Mozgás szkriptet a Kamera szülőjére kell helyeznie, és meg kell adnia annak referenciacéljait. Ez a szkript ezután kezeli a többi szkript elhelyezését, ahol lennie kell.

  1. A ProjektpanelSzkriptek mappájából húzza a Mozgás szkriptet a Hierarchia panelen található Kamera szülő objektumára.

    Képernyőkép a Projekt és hierarchia panelről. A mozgás ki van emelve.

  2. Kattintson a Kamera szülőelemre. A Hierarchia panelen húzza a Jobb kéz objektumot a Hierarchia panelről a Vezérlő hivatkozási célhoz az Inspector panelen. Állítsa a Felhasználói sebességértékét 5-re az alábbi képen látható módon.

    Képernyőkép a Hierarchia és az Inspector panelről. A vonal mindkét panelen összeköti a Right Handet.

12. fejezet – A Unity-projekt felépítése

A projekt Unity szakaszához szükséges összes elem elkészült, ezért ideje a Unityből felépíteni.

  1. Nyissa meg a Build Settings (Fájl>összeállítási beállításai) lehetőséget.

  2. A Létrehozási beállítások ablakban kattintson a Build (Build) elemre.

    Képernyőkép a BuildBeállítások ablakról, amelyen a Jelenetek a buildben látható.

  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 mappa elemre kattintva), és adja neki a BUILDS nevet.

    Képernyőkép Fájlkezelő, amelyen a Builds mappa ki van emelve.

    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.

      Képernyőkép a Fájlkezelőről, amelyen a MR_Azure_Insights mappa látható.

    2. Ha a MR_Azure_Application_Insights mappa van kijelölve, kattintson a Mappa kiválasztása elemre. A projekt létrehozása legalább egy percet vesz igénybe.

  4. A buildelést követően Fájlkezelő jelenik meg az új projekt helye.

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

Az 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 a Visual Studióban.

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

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

    Képernyőkép a Visual Studio Megoldáskonfiguráció képernyőről, amelyen a hibakeresés látható a menüsávon.

  4. Nyissa meg a Build (Build) menüt , és kattintson a Megoldás üzembe helyezése elemre az alkalmazás gépre való feltö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. Mozogjon a jelenet körül, közelítse meg az objektumokat, és nézze meg őket, amikor az Azure Insight Service elegendő eseményadatot gyűjtött, zöldre állítja a leggyakrabban megközelített objektumot.

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 Application Insights Service portálja

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

  1. Vissza az Application Insights Service portáljára.

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

    Képernyőkép a MyNewInsight panelről, amelyen a lehetőségek listája látható. A Metrics Explorer a Vizsgálat szakaszban található.

  3. A gráfot tartalmazó lapon nyílik meg, 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) is, amíg az adatok megjelennek a gráfban

    Képernyőkép a Metrics Explorerről, amelyen az események és a metrikák grafikonja látható.

  4. Az Események összesítése alkalmazásverzió szerint területen válassza az Események sávot, és tekintse meg az események részletes részletezését a nevükkel.

    Képernyőkép a Keresés panelről, amelyen egy egyéni eseményszűrő eredményei láthatók.

Az Application Insights Service-alkalmazás befejezése

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

Tanfolyam üdvözlőképernyője.

Bónusz gyakorlatok

1. gyakorlat

A manuális létrehozás helyett próbálja meg létrehozni az ObjectInScene objektumokat, é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 létrehozhat egy további objektumot.

2. gyakorlat

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