Condividi tramite


HoloLens (prima generazione) e Azure 309: Application Insights

Nota

Le esercitazioni di Mixed Reality Academy sono state progettate in base a HoloLens (prima generazione) e ai visori VR immersive di realtà mista. Pertanto, riteniamo importante lasciarle a disposizione degli sviluppatori a cui serve ancora materiale sussidiario per lo sviluppo di questi dispositivi. Queste esercitazioni non verranno aggiornate con i set di strumenti o le interazioni più recenti usati per HoloLens 2. Rimarranno invariate per consentire di continuare a lavorare sui dispositivi supportati. Ci sarà una nuova serie di esercitazioni che verranno pubblicate in futuro che dimostreranno come sviluppare per HoloLens 2. Questo avviso verrà aggiornato con un collegamento a tali esercitazioni quando vengono pubblicate.

Schermata iniziale dell'esercitazione di Realtà mista Academy.

In questo corso si apprenderà come aggiungere funzionalità di Application Insights a un'applicazione di realtà mista, usando l'API app Azure lication Insights per raccogliere analisi relative al comportamento dell'utente.

Application Insights è un servizio Microsoft che consente agli sviluppatori di raccogliere analisi dalle applicazioni e gestirle da un portale facile da usare. L'analisi può essere qualsiasi elemento, dalle prestazioni alle informazioni personalizzate che si vuole raccogliere. Per altre informazioni, visitare la pagina di Application Insights.

Dopo aver completato questo corso, si avrà un'applicazione visore VR immersive di realtà mista, che sarà in grado di eseguire le operazioni seguenti:

  1. Consentire all'utente di guardare e spostarsi intorno a una scena.
  2. Attivare l'invio di analisi al servizio Application Insights usando sguardo fisso e prossimità agli oggetti nella scena.
  3. L'app chiamerà anche il servizio, recuperando informazioni su quale oggetto è stato avvicinato di più dall'utente, nelle ultime 24 ore. L'oggetto cambierà il colore in verde.

Questo corso illustra come ottenere i risultati dal servizio Application Insights in un'applicazione di esempio basata su Unity. Sarà necessario applicare questi concetti a un'applicazione personalizzata che si sta creando.

Supporto di dispositivi

Corso HoloLens Visori VR immersive
MR e Azure 309: Application Insights ✔️ ✔️

Nota

Anche se questo corso è incentrato principalmente sui visori VR immersive di Windows Realtà mista, puoi anche applicare ciò che impari in questo corso a Microsoft HoloLens. Mentre segui il corso, vedrai le note su eventuali modifiche che potresti dover usare per supportare HoloLens. Quando si usa HoloLens, è possibile notare un'eco durante l'acquisizione vocale.

Prerequisiti

Nota

Questa esercitazione è progettata per gli sviluppatori che hanno esperienza di base con Unity e C#. Tenere presente anche che i prerequisiti e le istruzioni scritte all'interno di questo documento rappresentano ciò che è stato testato e verificato al momento della scrittura (luglio 2018). Sei libero di usare il software più recente, come elencato all'interno dell'articolo installare gli strumenti , anche se non si deve presumere che le informazioni in questo corso corrisponderanno perfettamente a ciò che troverai nel software più recente rispetto a quello elencato di seguito.

Per questo corso è consigliabile usare l'hardware e il software seguenti:

Prima di iniziare

Per evitare problemi durante la compilazione di questo progetto, è consigliabile creare il progetto in questa esercitazione in una cartella radice o quasi radice (i percorsi delle cartelle lunghe possono causare problemi in fase di compilazione).

Avviso

Tenere presente che i dati che passano ad Application Insights richiedono tempo, quindi essere pazienti. Per verificare se il servizio ha ricevuto i dati, consultare il capitolo 14, che mostrerà come navigare nel portale.

Capitolo 1 - Portale di Azure

Per usare Application Insights, è necessario creare e configurare un servizio Application Insights nel portale di Azure.

  1. Accedere al portale di Azure.

    Nota

    Se non si ha già un account Azure, è necessario crearne uno. Se si segue questa esercitazione in una classe o in una situazione di laboratorio, chiedere all'insegnante o a uno dei prottori di assistenza per configurare il nuovo account.

  2. Dopo aver eseguito l'accesso, fare clic su Nuovo nell'angolo superiore sinistro e cercare Application Insights e fare clic su INVIO.

    Nota

    La parola New potrebbe essere stata sostituita con Crea una risorsa, nei portali più recenti.

    Screenshot che mostra il portale di Azure, informazioni dettagliate è evidenziato nel riquadro Tutto.

  3. La nuova pagina a destra fornirà una descrizione del servizio app Azure lication Insights. Nella parte inferiore sinistra di questa pagina selezionare il pulsante Crea per creare un'associazione con questo servizio.

    Screenshot della schermata di Application Insights, Crea evidenziato.

  4. Dopo aver fatto clic su Crea:

    1. Inserire il nome desiderato per questa istanza del servizio.

    2. In Tipo di applicazione selezionare Generale.

    3. Selezionare una sottoscrizione appropriata.

    4. Scegliere un gruppo di risorse o crearne uno nuovo. Un gruppo di risorse consente di monitorare, controllare l'accesso, effettuare il provisioning e gestire la fatturazione per una raccolta di asset di Azure. È consigliabile mantenere tutti i servizi di Azure associati a un singolo progetto (ad esempio, ad esempio questi corsi) in un gruppo di risorse comune.

      Per altre informazioni sui gruppi di risorse di Azure, vedere l'articolo relativo al gruppo di risorse.

    5. Selezionare una località.

    6. È anche necessario verificare di aver compreso le condizioni e le condizioni applicate al servizio.

    7. Seleziona Crea.

      Screenshot della finestra di Application Insights. Nome e tipo di applicazione sono evidenziati.

  5. Dopo aver fatto clic su Crea, è necessario attendere che il servizio venga creato, l'operazione potrebbe richiedere un minuto.

  6. Una notifica verrà visualizzata nel portale dopo la creazione dell'istanza del servizio.

    Screenshot che mostra una parte della barra multifunzione del menu, l'icona di notifica è evidenziata.

  7. Selezionare le notifiche per esplorare la nuova istanza del servizio.

    Screenshot che mostra la finestra di dialogo Distribuzione riuscita, vai alla risorsa evidenziata.

  8. Fare clic sul pulsante Vai alla risorsa nella notifica per esplorare la nuova istanza del servizio. Verrà visualizzata la nuova istanza del servizio Application Insights.

    Screenshot che mostra l'istanza del servizio Application Insights in cui il nome dell'istanza è MyNewInsight.

    Nota

    Mantenere aperta e facile l'accesso a questa pagina Web, si tornerà qui spesso per visualizzare i dati raccolti.

    Importante

    Per implementare Application Insights, è necessario usare tre (3) valori specifici: Chiave di strumentazione, ID applicazione e Chiave API. Di seguito verrà illustrato come recuperare questi valori dal servizio. Assicurarsi di annotare questi valori in una pagina vuota del Blocco note, perché verranno usati a breve nel codice.

  9. Per trovare la chiave di strumentazione, è necessario scorrere verso il basso l'elenco delle funzioni del servizio e selezionare Proprietà, la scheda visualizzata visualizzerà la chiave del servizio.

    Screenshot che mostra le funzioni del servizio, le proprietà sono evidenziate nella sezione Configura e la chiave di strumentazione è evidenziata nel riquadro principale.

  10. Di seguito sono riportate le proprietà disponibili per l'accesso all'API, che è necessario fare clic. Il pannello a destra fornirà l'ID applicazione dell'app.

    Screenshot che mostra le funzioni del servizio, è evidenziato L'opzione A P I Access. Creare una chiave P I e un'applicazione I D sono evidenziate nel riquadro principale.

  11. Con il pannello ID applicazione ancora aperto, fare clic su Crea chiave API, che aprirà il pannello Crea chiave API.

    Screenshot che mostra il pannello crea un tasto P I.

  12. All'interno del pannello Crea chiave API aprire il pannello Crea chiave API, digitare una descrizione e selezionare le tre caselle.

  13. Fare clic su Genera chiave. La chiave API verrà creata e visualizzata.

    Screenshot del pannello Crea chiave P I che mostra le nuove informazioni sulla chiave del servizio.

    Avviso

    Questa è l'unica volta che verrà visualizzata la chiave del servizio, quindi assicurarsi di crearne una copia ora.

Capitolo 2 - Configurare il progetto Unity

Di seguito è riportata una configurazione tipica per lo sviluppo con la realtà mista e, di conseguenza, è un modello valido per altri progetti.

  1. Aprire Unity e fare clic su Nuovo.

    Screenshot della finestra progetti Unity. Non vengono visualizzate informazioni sul progetto.

  2. A questo punto è necessario specificare un nome di progetto Unity, inserire MR_Azure_Application_Insights. Assicurarsi che il modello sia impostato su 3D. Impostare La posizione su un punto appropriato per l'utente (tenere presente che più vicino alle directory radice è preferibile). Fare quindi clic su Crea progetto.

    Screenshot della finestra Dei nuovi progetti unity che mostra le informazioni sul progetto.

  3. Con Unity aperto, vale la pena controllare che l'editor di script predefinito sia impostato su Visual Studio. Passare a Modifica > preferenze e quindi dalla nuova finestra passare a Strumenti esterni. Modificare l'editor di script esterni in Visual Studio 2017. Chiudere la finestra Preferenze .

    Screenshot che mostra che Visual Studio è configurato come editor di script esterno.

  4. Passare quindi a Impostazioni compilazione file > e impostare la piattaforma su piattaforma UWP (Universal Windows Platform), facendo clic sul pulsante Cambia piattaforma.

    Screenshot della finestra Impostazioni di compilazione che mostra l'elenco di selezione Piattaforma. piattaforma UWP (Universal Windows Platform) selezionato.

  5. Passare a Impostazioni di compilazione file > e assicurarsi che:

    1. Il dispositivo di destinazione è impostato su Qualsiasi dispositivo

      Per Microsoft HoloLens impostare Dispositivo di destinazione su HoloLens.

    2. Il tipo di compilazione è impostato su D3D

    3. L'SDK è impostato su Latest installed (Versione più recente installata)

    4. Compilazione ed esecuzione è impostata su Computer locale

    5. Salvare la scena e aggiungerla alla compilazione.

      1. A tale scopo, selezionare Aggiungi scene aperte. Verrà visualizzata una finestra di salvataggio.

        Screenshot della finestra Impostazioni di compilazione, è selezionata l'opzione Aggiungi scene aperte.

      2. Creare una nuova cartella per questa e qualsiasi scena futura, quindi fare clic sul pulsante Nuova cartella per creare una nuova cartella, denominarla Scene.

        Screenshot della finestra Salva scena, la cartella Scene è selezionata.

      3. Aprire la cartella Scenes appena creata e quindi nel campo Nome file: testo digitare ApplicationInsightsScene, quindi fare clic su Salva.

        Screenshot della finestra Salva scena con il nome file immesso.

  6. Le impostazioni rimanenti, in Impostazioni di compilazione, devono essere lasciate come predefinite per il momento.

  7. Nella finestra Impostazioni di compilazione selezionare Impostazioni lettore, verrà aperto il pannello correlato nello spazio in cui si trova il controllo.

    Screenshot della scheda Inspector che mostra Le impostazioni del lettore.

  8. In questo pannello è necessario verificare alcune impostazioni:

    1. Nella scheda Altre impostazioni :

      1. La versione del runtime di scripting deve essere sperimentale (equivalente a .NET 4.6), che attiverà la necessità di riavviare l'editor.

      2. Il back-end di scripting deve essere .NET

      3. Il livello di compatibilità api deve essere .NET 4.6

      Screenshot della scheda Inspector che mostra i dettagli nella sezione di configurazione di Altre impostazioni.

    2. Nella scheda Impostazioni di pubblicazione, in Funzionalità selezionare:

      • InternetClient

        Screenshot dell'elenco Funzionalità, il client Internet è selezionato.

    3. Più in basso nel pannello, in Impostazioni XR (disponibile sotto Impostazioni di pubblicazione), selezionare Virtual Reality Supported (Realtà virtuale supportata), assicurarsi che Windows Realtà mista SDK sia stato aggiunto.

      Screenshot della sezione X R Settings (Impostazioni X R), Virtual Reality Supported (Realtà virtuale supportata) selezionata.

  9. Tornare in Impostazioni di compilazione, i progetti C# di Unity non sono più disattivati. Selezionare la casella di controllo accanto a questa.

  10. Chiudere la finestra Build Settings (Impostazioni di compilazione).

  11. Salvare la scena e il progetto (FILE>SAVE SCENE/FILE>SAVE PROJECT).

Capitolo 3 - Importare il pacchetto Unity

Importante

Se si vuole ignorare i componenti di configurazione di Unity di questo corso e continuare direttamente nel codice, è possibile scaricare questo pacchetto Azure-MR-309.unitypackage, importarlo nel progetto come pacchetto personalizzato. Questo conterrà anche le DLL del capitolo successivo. Dopo l'importazione, continuare dal capitolo 6.

Importante

Per usare Application Insights in Unity, è necessario importare la DLL, insieme alla DLL Newtonsoft. Esiste attualmente un problema noto in Unity che richiede la riconfigurazione dei plug-in dopo l'importazione. Questi passaggi (da 4 a 7 in questa sezione) non saranno più necessari dopo la risoluzione del bug.

Per importare Application Insights nel proprio progetto, assicurarsi di aver scaricato il file '.unitypackage', contenente i plug-in. Procedere quindi come segue:

  1. Aggiungere the.unitypackage** a Unity usando l'opzione di menu Asset > Importa pacchetto > personalizzato pacchetto.

  2. Nella casella Importa pacchetto Unity visualizzata verificare che tutti gli elementi in (e inclusi) Plug-in siano selezionati.

    Screenshot della finestra di dialogo Importa pacchetto Unity che mostra tutti gli elementi selezionati.

  3. Fare clic sul pulsante Importa per aggiungere gli elementi al progetto.

  4. Passare alla cartella Insights in Plug-in nella visualizzazione Progetto e selezionare solo i plug-in seguenti:

    • Microsoft.ApplicationInsights

    Screenshot del pannello Progetto, la cartella Insights è aperta.

  5. Con questo plug-in selezionato, assicurarsi che Qualsiasi piattaforma sia deselezionata, quindi assicurarsi che WSAPlayer sia deselezionato, quindi fare clic su Applica. In questo modo è sufficiente verificare che i file siano configurati correttamente.

    Screenshot del pannello Controllo che mostra l'editor e la versione autonoma selezionata.

    Nota

    Contrassegnando i plug-in come questo, li configura in modo che vengano usati solo nell'editor di Unity. Nella cartella WSA è presente un set diverso di DLL che verranno usate dopo l'esportazione del progetto da Unity.

  6. Successivamente, è necessario aprire la cartella WSA all'interno della cartella Insights . Verrà visualizzata una copia dello stesso file configurato. Selezionare questo file e quindi nel controllo verificare che Qualsiasi piattaforma sia deselezionata, quindi assicurarsi che sia selezionato solo WSAPlayer. Fare clic su Applica.

    Screenshot del pannello Inspector che mostra W S A Player selezionato.

  7. Ora dovrai seguire i passaggi da 4 a 6, ma per i plug-in Newtonsoft . Vedere lo screenshot seguente per l'aspetto del risultato.

    Screenshot di quattro visualizzazioni dei pannelli Project e Inspector che mostrano i risultati della configurazione delle selezioni della cartella e del plug-in Newtonsoft.

Capitolo 4 - Configurare la fotocamera e i controlli utente

In questo capitolo si configureranno la fotocamera e i controlli per consentire all'utente di vedere e spostarsi nella scena.

  1. Fare clic con il pulsante destro del mouse in un'area vuota nel pannello Gerarchia, quindi scegliere Crea>vuoto.

    Screenshot del pannello Gerarchia, è selezionato Crea vuoto.

  2. Rinominare il nuovo GameObject vuoto in Elemento padre fotocamera.

    Screenshot del pannello Gerarchia con l'opzione Padre fotocamera selezionata. Pannello Inspector (Controllo)

  3. Fare clic con il pulsante destro del mouse in un'area vuota nel pannello gerarchia, quindi su Oggetto 3D, quindi su Sphere.

  4. Rinominare la sfera in mano destra.

  5. Impostare la scala di trasformazione della mano destra su 0.1, 0.1, 0.1

    Screenshot dei pannelli Hierarchy and Inspector (Gerarchia e controllo), la sezione Transform (Trasforma) nel pannello Inspector (Controllo) è evidenziata.

  6. Rimuovere il componente Collisore Sphere dalla mano destra facendo clic sull'ingranaggio nel componente Collisore sphere e quindi su Rimuovi componente.

    Screenshot del pannello Controllo, l'icona a forma di ingranaggio e Rimuovi componente sono evidenziate nella sezione Collisore sphere.

  7. Nel pannello Hierarchy (Gerarchia) trascinare la fotocamera principale e gli oggetti Right Hand nell'oggetto Camera Parent .

    Screenshot del pannello Gerarchia con la fotocamera principale selezionata, il pannello Controllo mostra la fotocamera principale selezionata.

  8. Impostare la posizione di trasformazione sia della fotocamera principale che dell'oggetto Mano destra su 0, 0, 0.

    Screenshot del pannello Gerarchia con la fotocamera principale selezionata, le impostazioni di trasformazione sono evidenziate nel pannello Controllo.

    Screenshot del pannello Hierarchy con l'opzione Destra selezionata, Le impostazioni di trasformazione vengono evidenziate nel pannello Inspector (Controllo).

Capitolo 5 - Configurare gli oggetti nella scena unity

A questo punto si creeranno alcune forme di base per la scena, con cui l'utente può interagire.

  1. Fare clic con il pulsante destro del mouse in un'area vuota nel pannello Gerarchia, quindi su Oggetto 3D, quindi scegliere Piano.

  2. Impostare La posizione della trasformazione del piano su 0, -1, 0.

  3. Impostare Scala trasformazione piano su 5, 1, 5.

    Screenshot dei pannelli Scene, Hierarchy e Inspector. La sezione Trasforma nel pannello Inspector (Controllo) è evidenziata.

  4. Creare un materiale di base da usare con l'oggetto Plane , in modo che le altre forme siano più facili da vedere. Passare al pannello del progetto, fare clic con il pulsante destro del mouse, quindi scegliere Crea, quindi Cartella, per creare una nuova cartella. Denominarlo Materials.

    Screenshot del pannello Progetto che mostra l'opzione Crea e cartella evidenziata. Screenshot del pannello Progetto. I materiali sono evidenziati nel riquadro Asset.

  5. Aprire la cartella Materiali, quindi fare clic con il pulsante destro del mouse, scegliere Crea, quindi Materiale per creare un nuovo materiale. Denominarlo Blu.

    Screenshot del pannello Progetto che mostra l'opzione Crea e materiale evidenziata. Screenshot del pannello Progetto. Il blu è evidenziato nel riquadro Materiali.

  6. Con il nuovo materiale Blu selezionato, guarda il controllo e fai clic sulla finestra rettangolare accanto ad Albedo. Selezionare un colore blu (l'immagine seguente è Colore esadecimale: #3592FFFF). Fare clic sul pulsante chiudi dopo aver scelto.

    Screenshot del pannello Inspector (Controllo). La sezione colore è evidenziata.

  7. Trascinare il nuovo materiale dalla cartella Materiali, nel piano appena creato, all'interno della scena o rilasciarlo nell'oggetto Plane all'interno della gerarchia.

    Screenshot del pannello Scena che mostra il nuovo materiale dalla cartella Materiali.

  8. Fare clic con il pulsante destro del mouse in un'area vuota nel pannello Gerarchia, quindi su Oggetto 3D Capsule.

    • Con l'opzione Capsule selezionata, modifica la relativa posizione di trasformazione in: -10, 1, 0.
  9. Fare clic con il pulsante destro del mouse in un'area vuota nel pannello Gerarchia, quindi su Oggetto 3D, Cubo.

    • Con l'opzione Cube selezionata, modifica la relativa posizione trasforma in: 0, 0, 10.
  10. Fare clic con il pulsante destro del mouse in un'area vuota nel pannello Gerarchia, quindi su Oggetto 3D, Sphere.

    • Con l'opzione Sphere selezionata, modifica la relativa posizione di trasformazione in: 10, 0, 0.

    Screenshot dei pannelli Scene, Hierarchy e Inspector. La capsula è selezionata nel pannello Gerarchia.

    Nota

    Questi valori Position sono suggerimenti. Sei libero di impostare le posizioni degli oggetti su qualsiasi cosa vuoi, anche se è più facile per l'utente dell'applicazione se le distanze degli oggetti non sono troppo lontane dalla fotocamera.

  11. Quando l'applicazione è in esecuzione, deve essere in grado di identificare gli oggetti all'interno della scena, per ottenere questo risultato, devono essere contrassegnati. Selezionare uno degli oggetti e nel pannello Inspector (Controllo) fare clic su Add Tag (Aggiungi tag). In questo modo il controllo verrà scambiato con il pannello Tag e livelli .

    Screenshot del pannello Controllo che mostra l'opzione Aggiungi tag evidenziata. Screenshot del pannello Inspector che mostra tag e livelli evidenziati.

  12. Fare clic sul simbolo + (più) e quindi digitare il nome del tag come ObjectInScene.

    Screenshot del pannello Inspector con Tag e Layer selezionati. La finestra di dialogo Nuovo nome tag è evidenziata.

    Avviso

    Se si usa un nome diverso per il tag, sarà necessario assicurarsi che questa modifica venga apportata anche agli script DataFromAnalytics, ObjectTrigger e Gaze, in modo che gli oggetti vengano trovati e rilevati all'interno della scena.

  13. Dopo aver creato il tag, è ora necessario applicarlo a tutti e tre gli oggetti. Nella gerarchia tenere premuto MAIUSC, quindi fare clic sugli oggetti Capsule, Cube e Sphere, quindi nel controllo fare clic sul menu a discesa accanto a Tag, quindi fare clic sul tag ObjectInScene creato.

    Screenshot del pannello Inspector (Controllo), una freccia punta a Tag. Il menu Senza tag mostra che è selezionata l'opzione Non contrassegnata e ObjectInScene è selezionata. Screenshot che mostra due menu con l'opzione Crea e cartella evidenziata.

Capitolo 6 - Creare la classe ApplicationInsightsTracker

Il primo script da creare è ApplicationInsightsTracker, responsabile di:

  1. Creazione di eventi in base alle interazioni dell'utente da inviare a app Azure lication Insights.

  2. Creazione di nomi di evento appropriati, a seconda dell'interazione dell'utente.

  3. Invio di eventi all'istanza del servizio Application Insights.

Per creare questa classe:

  1. Fare clic con il pulsante destro del mouse nel pannello del progetto, quindi scegliere Crea>cartella. Denominare la cartella Scripts.

    Screenshot del pannello Progetti. L'icona della cartella Scripts è evidenziata nel riquadro Asset. Screenshot che mostra le opzioni in cui sono selezionate le opzioni Create and C# Script (Crea e script C#).

  2. Dopo la creazione della cartella Scripts , fare doppio clic su di essa per aprirla. Quindi, all'interno di tale cartella, fare clic con il pulsante destro del mouse su Crea>script C#. Assegnare allo script il nome ApplicationInsightsTracker.

  3. Fare doppio clic sul nuovo script ApplicationInsightsTracker per aprirlo con Visual Studio.

  4. Aggiornare gli spazi dei nomi nella parte superiore dello script come indicato di seguito:

        using Microsoft.ApplicationInsights;
        using Microsoft.ApplicationInsights.DataContracts;
        using Microsoft.ApplicationInsights.Extensibility;
        using UnityEngine;
    
  5. All'interno della classe inserire le variabili seguenti:

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

    Nota

    Impostare i valori instrumentationKey, applicationId e API_Key in modo appropriato, usando le chiavi del servizio dal portale di Azure, come indicato nel capitolo 1, passaggio 9 e versioni successive.

  6. Aggiungere quindi i metodi Start() e Awake(), che verranno chiamati quando la classe inizializza:

        /// <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. Aggiungere i metodi responsabili dell'invio degli eventi e delle metriche registrati dall'applicazione:

        /// <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. Assicurarsi di salvare le modifiche in Visual Studio prima di tornare a Unity.

Capitolo 7 - Creare lo script sguardo fisso

Lo script successivo da creare è lo script gaze . Questo script è responsabile della creazione di un Raycast che verrà proiettato in avanti dalla fotocamera principale, per rilevare l'oggetto che l'utente sta esaminando. In questo caso, Raycast dovrà identificare se l'utente sta esaminando un oggetto con il tag ObjectInScene e quindi contare per quanto tempo l'utente guarda l'oggetto.

  1. Fare doppio clic sulla cartella Scripts per aprirla.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella Scripts e scegliere Crea>script C#. Assegnare allo script il nome Gaze.

  3. Fare doppio clic sullo script per aprirlo con Visual Studio.

  4. Sostituire il codice esistente con quello seguente:

        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. È ora necessario aggiungere il codice per i metodi Awake() e Start().

        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. All'interno della classe Gaze aggiungere il codice seguente nel metodo Update() per proiettare un Raycast e rilevare l'hit di destinazione:

        /// <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. Aggiungere il metodo ResetFocusedObject() per inviare dati ad Application Insights quando l'utente ha esaminato un oggetto.

        /// <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. A questo punto è stato completato lo script sguardo fisso . Salvare le modifiche in Visual Studio prima di tornare a Unity.

Capitolo 8 - Creare la classe ObjectTrigger

Lo script successivo che è necessario creare è ObjectTrigger, che è responsabile di:

  • Aggiunta di componenti necessari per la collisione alla fotocamera principale.
  • Rilevamento se la fotocamera si trova vicino a un oggetto contrassegnato come ObjectInScene.

Per creare lo script:

  1. Fare doppio clic sulla cartella Scripts per aprirla.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella Scripts e scegliere Crea>script C#. Assegnare allo script il nome ObjectTrigger.

  3. Fare doppio clic sullo script per aprirlo con Visual Studio. Sostituire il codice esistente con quello seguente:

        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. Assicurarsi di salvare le modifiche in Visual Studio prima di tornare a Unity.

Capitolo 9 - Creare la classe DataFromAnalytics

A questo punto è necessario creare lo script DataFromAnalytics , responsabile di:

  • Recupero dei dati di analisi su quale oggetto è stato avvicinato dalla fotocamera il più possibile.
  • Uso delle chiavi del servizio che consentono la comunicazione con l'istanza del servizio app Azure lication Insights.
  • Ordinamento degli oggetti nella scena, in base al quale ha il numero di eventi più alto.
  • Modifica del colore del materiale, dell'oggetto più avvicinato, in verde.

Per creare lo script:

  1. Fare doppio clic sulla cartella Scripts per aprirla.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella Scripts e scegliere Crea>script C#. Denominare lo script DataFromAnalytics.

  3. Fare doppio clic sullo script per aprirlo con Visual Studio.

  4. Inserire gli spazi dei nomi seguenti:

        using Newtonsoft.Json;
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. All'interno dello script inserire quanto segue:

        /// <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. All'interno della classe DataFromAnalytics , subito dopo il metodo Start(), aggiungere il metodo seguente denominato FetchAnalytics(). Questo metodo è responsabile del popolamento dell'elenco di coppie chiave-valore, con un GameObject e un numero di conteggio eventi segnaposto. Inizializza quindi la coroutine GetWebRequest(). La struttura di query della chiamata ad Application Insights è disponibile anche all'interno di questo metodo, come endpoint dell'URL di query.

        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. Sotto il metodo FetchAnalytics() aggiungere un metodo denominato GetWebRequest(), che restituisce un IEnumerator. Questo metodo è responsabile della richiesta del numero di volte in cui un evento, corrispondente a un GameObject specifico, è stato chiamato in Application Insights. Quando vengono restituite tutte le query inviate, viene chiamato il metodo DetermineWinner().

        /// <summary>
        /// Requests the data count for number of events, according to the
        /// input query URL.
        /// </summary>
        /// <param name="webQueryPair">Query URL and the list number count.</param>
        /// <returns></returns>
        private IEnumerator GetWebRequest(KeyValuePair<string, int> webQueryPair)
        {
            // Set the URL and count as their own variables (for readability).
            string url = webQueryPair.Key;
            int currentCount = webQueryPair.Value;
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(url))
            {
                DownloadHandlerBuffer handlerBuffer = new DownloadHandlerBuffer();
    
                unityWebRequest.downloadHandler = handlerBuffer;
    
                unityWebRequest.SetRequestHeader("host", "api.applicationinsights.io");
    
                unityWebRequest.SetRequestHeader("x-api-key", ApplicationInsightsTracker.Instance.API_Key);
    
                yield return unityWebRequest.SendWebRequest();
    
                if (unityWebRequest.isNetworkError)
                {
                    // Failure with web request.
                    Debug.Log("<color=red>Error Sending:</color> " + unityWebRequest.error);
                }
                else
                {
                    // This query has returned, so add to the current count.
                    _queriesReturned++;
    
                    // Initialize event count integer.
                    int eventCount = 0;
    
                    // Deserialize the response with the custom Analytics class.
                    Analytics welcome = JsonConvert.DeserializeObject<Analytics>(unityWebRequest.downloadHandler.text);
    
                    // Get and return the count for the Event
                    if (int.TryParse(welcome.OdataCount, out eventCount) == false)
                    {
                        // Parsing failed. Can sometimes mean that the Query URL was incorrect.
                        Debug.Log("<color=red>Failure to Parse Data Results. Check Query URL for issues.</color>");
                    }
                    else
                    {
                        // Overwrite the current pair, with its actual values, now that the event count is known.
                        _pairedObjectsWithEventCount[currentCount] = new KeyValuePair<GameObject, int>(_pairedObjectsWithEventCount[currentCount].Key, eventCount);
                    }
    
                    // If all queries (compared with the number which was sent away) have 
                    // returned, then run the determine winner method. 
                    if (_queriesReturned == _pairedObjectsWithEventCount.Count)
                    {
                        DetermineWinner();
                    }
                }
            }
        }
    
  8. Il metodo successivo è DetermineWinner(), che ordina l'elenco di coppie GameObject e Int, in base al numero di eventi più alto. Cambia quindi il colore del materiale di tale GameObject in verde (come feedback per il conteggio più alto). Verrà visualizzato un messaggio con i risultati dell'analisi.

        /// <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. Aggiungere la struttura di classe che verrà usata per deserializzare l'oggetto JSON, ricevuto da Application Insights. Aggiungere queste classi nella parte inferiore del file di classe DataFromAnalytics , all'esterno della definizione della classe.

        /// <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. Assicurarsi di salvare le modifiche in Visual Studio prima di tornare a Unity.

Capitolo 10 - Creare la classe Movimento

Lo script di spostamento è lo script successivo che sarà necessario creare. È responsabile delle operazioni seguenti:

  • Spostando la fotocamera principale in base alla direzione verso cui la fotocamera sta guardando.
  • Aggiunta di tutti gli altri script agli oggetti scena.

Per creare lo script:

  1. Fare doppio clic sulla cartella Scripts per aprirla.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella Scripts e scegliere Crea>script C#. Assegnare allo script il nome Movimento.

  3. Fare doppio clic sullo script per aprirlo con Visual Studio.

  4. Sostituire il codice esistente con quello seguente:

        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. All'interno della classe Movement, sotto il metodo Update() vuoto, inserire i metodi seguenti che consentono all'utente di usare il controller della mano per spostarsi nello spazio virtuale:

        /// <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. Aggiungere infine la chiamata al metodo all'interno del metodo Update().

        // Update is called once per frame
        void Update()
        {
            UpdateControllerState();
        }
    
  7. Assicurarsi di salvare le modifiche in Visual Studio prima di tornare a Unity.

Capitolo 11 - Configurazione dei riferimenti agli script

In questo capitolo è necessario posizionare lo script movimento nell'elemento padre della fotocamera e impostarne le destinazioni di riferimento. Tale script gestirà quindi l'inserimento degli altri script in cui devono trovarsi.

  1. Dalla cartella Scripts nel pannello progetto trascinare lo script di spostamento nell'oggetto Padre fotocamera, che si trova nel pannello Gerarchia.

    Screenshot dei pannelli Progetto e Gerarchia. Il movimento è evidenziato.

  2. Fare clic sul padre della fotocamera. Nel pannello Hierarchy (Gerarchia) trascinare l'oggetto Right Hand dal Pannello gerarchia alla destinazione di riferimento Controller nel pannello di controllo. Impostare Velocità utente su 5, come illustrato nell'immagine seguente.

    Screenshot che mostra i pannelli Hierarchy e Inspector. Una linea collega la mano destra su entrambi i pannelli.

Capitolo 12 - Compilare il progetto Unity

Tutto ciò che serve per la sezione Unity di questo progetto è stato completato, quindi è il momento di compilarlo da Unity.

  1. Passare a Build Settings (Impostazioni compilazione file>).

  2. Nella finestra Build Settings (Impostazioni compilazione) fare clic su Build (Compila).

    Screenshot della finestra Impostazioni di compilazione che mostra scene in compilazione.

  3. Verrà visualizzata una finestra di Esplora file che richiede una posizione per la compilazione. Creare una nuova cartella (facendo clic su Nuova cartella nell'angolo superiore sinistro) e denominarla BUILD.

    Screenshot di Esplora file che mostra la cartella Compilazioni evidenziata.

    1. Aprire la nuova cartella BUILD e creare un'altra cartella (usando una nuova cartella) e denominarla MR_Azure_Application_Insights.

      Screenshot di Esplora file che mostra la cartella MR_Azure_Insights.

    2. Con la MR_Azure_Application_Insights cartella selezionata, fare clic su Seleziona cartella. La compilazione del progetto richiederà un minuto.

  4. Dopo la compilazione, Esplora file verrà visualizzata la posizione del nuovo progetto.

Capitolo 13 - Distribuire MR_Azure_Application_Insights'app nel computer

Per distribuire l'app MR_Azure_Application_Insights nel computer locale:

  1. Aprire il file della soluzione dell'app MR_Azure_Application_Insights in Visual Studio.

  2. Nella piattaforma della soluzione selezionare x86, Computer locale.

  3. Nella configurazione della soluzione selezionare Debug.

    Screenshot della schermata Configurazione della soluzione di Visual Studio che mostra Debug nella barra dei menu.

  4. Passare al menu Compila e fare clic su Distribuisci soluzione per trasferire localmente l'applicazione nel computer.

  5. L'app dovrebbe ora essere visualizzata nell'elenco delle app installate, pronte per l'avvio.

  6. Avviare l'applicazione di realtà mista.

  7. Spostarsi nella scena, avvicinando gli oggetti e esaminandoli, quando il servizio Insight di Azure ha raccolto dati di eventi sufficienti, imposta l'oggetto che è stato avvicinato al più verde.

Importante

Mentre il tempo medio di attesa per gli eventi e le metriche da raccogliere dal servizio richiede circa 15 minuti, in alcune occasioni potrebbe richiedere fino a 1 ora.

Capitolo 14 - Portale del servizio Application Insights

Dopo aver eseguito il roaming della scena e aver guardato diversi oggetti, è possibile visualizzare i dati raccolti nel portale del servizio Application Insights.

  1. Tornare al portale del servizio Application Insights.

  2. Selezionare Esplora metriche.

    Screenshot del pannello MyNewInsight che mostra l'elenco delle opzioni. Esplora metriche è elencato nella sezione Analisi.

  3. Verrà aperta in una scheda contenente il grafico, che rappresenta gli eventi e le metriche correlate all'applicazione. Come accennato in precedenza, potrebbero essere necessari alcuni minuti (fino a 1 ora) per visualizzare i dati nel grafico

    Screenshot di Esplora metriche che mostra gli eventi e il grafico delle metriche.

  4. Selezionare la barra Eventi nella sezione Totale eventi per versione applicazione per visualizzare una suddivisione dettagliata degli eventi con i relativi nomi.

    Screenshot del pannello Ricerca che mostra i risultati di un filtro eventi personalizzato.

Applicazione del servizio Application Insights completata

È stata creata un'app di realtà mista che sfrutta il servizio Application Insights per monitorare l'attività dell'utente all'interno dell'app.

Schermata iniziale del corso.

Esercizi bonus

Esercizio 1

Provare a generare, anziché creare manualmente, gli oggetti ObjectInScene e impostarne le coordinate sul piano all'interno degli script. In questo modo, è possibile chiedere ad Azure quale fosse l'oggetto più diffuso (dai risultati dello sguardo fisso o della prossimità) e generare uno di questi oggetti aggiuntivo .

Esercizio 2

Ordinare i risultati di Application Insights in base al tempo, in modo da ottenere i dati più rilevanti e implementare i dati sensibili al tempo nell'applicazione.