MR e Azure 305: Funzioni e archiviazioneMR and Azure 305: Functions and storage


Nota

Le esercitazioni di Mixed Reality Academy sono state progettate in base a HoloLens (prima generazione) e ai visori VR immersive di realtà mista.The Mixed Reality Academy tutorials were designed with HoloLens (1st gen) and Mixed Reality Immersive Headsets in mind. Pertanto, riteniamo importante lasciarle a disposizione degli sviluppatori a cui serve ancora materiale sussidiario per lo sviluppo di questi dispositivi.As such, we feel it is important to leave these tutorials in place for developers who are still looking for guidance in developing for those devices. Queste esercitazioni non verranno aggiornate con i set di strumenti o le interazioni più recenti usati per HoloLens 2.These tutorials will not be updated with the latest toolsets or interactions being used for HoloLens 2. Rimarranno invariate per consentire di continuare a lavorare sui dispositivi supportati.They will be maintained to continue working on the supported devices. In futuro sarà disponibile una nuova serie di esercitazioni che illustrano come sviluppare per HoloLens 2.There will be a new series of tutorials that will be posted in the future that will demonstrate how to develop for HoloLens 2. Questo avviso verrà aggiornato con un collegamento a queste esercitazioni quando vengono pubblicate.This notice will be updated with a link to those tutorials when they are posted.


prodotto finale-inizio

In questo corso si apprenderà come creare e usare funzioni di Azure e come archiviare i dati con una risorsa di archiviazione di Azure, all'interno di un'applicazione di realtà mista.In this course, you will learn how to create and use Azure Functions and store data with an Azure Storage resource, within a mixed reality application.

Funzioni di Azure è un servizio Microsoft che consente agli sviluppatori di eseguire piccole porzioni di codice, "funzioni", in Azure.Azure Functions is a Microsoft service, which allows developers to run small pieces of code, 'functions', in Azure. Questo consente di delegare il lavoro al cloud, anziché l'applicazione locale, che può avere molti vantaggi.This provides a way to delegate work to the cloud, rather than your local application, which can have many benefits. Funzioni di Azure supporta diversi linguaggi di sviluppo, tra cui C # , F # , Node.js, Java e php.Azure Functions supports several development languages, including C#, F#, Node.js, Java, and PHP. Per altre informazioni, vedere l' articolo funzioni di Azure.For more information, visit the Azure Functions article.

Archiviazione di Azure è un servizio cloud Microsoft che consente agli sviluppatori di archiviare i dati, con l'assicurazione che saranno a disponibilità elevata, protezione, durabilità, scalabilità e ridondanza.Azure Storage is a Microsoft cloud service, which allows developers to store data, with the insurance that it will be highly available, secure, durable, scalable, and redundant. Ciò significa che Microsoft gestirà tutta la manutenzione e i problemi critici.This means Microsoft will handle all maintenance, and critical problems for you. Per altre informazioni, vedere l' articolo archiviazione di Azure.For more information, visit the Azure Storage article.

Dopo aver completato questo corso, si disporrà di un'applicazione con un auricolare immersiva a realtà mista che sarà in grado di eseguire le operazioni seguenti:Having completed this course, you will have a mixed reality immersive headset application which will be able to do the following:

  1. Consente all'utente di guardare una scena.Allow the user to gaze around a scene.
  2. Attiva la generazione di oggetti quando l'utente guarda un "pulsante" 3D.Trigger the spawning of objects when the user gazes at a 3D 'button'.
  3. Gli oggetti generati verranno scelti da una funzione di Azure.The spawned objects will be chosen by an Azure Function.
  4. Quando viene generato ogni oggetto, l'applicazione archivia il tipo di oggetto in un file di Azure, che si trova in archiviazione di Azure.As each object is spawned, the application will store the object type in an Azure File, located in Azure Storage.
  5. Al caricamento di una seconda volta, i dati dei file di Azure verranno recuperati e usati per riprodurre le azioni di generazione dall'istanza precedente dell'applicazione.Upon loading a second time, the Azure File data will be retrieved, and used to replay the spawning actions from the previous instance of the application.

Nell'applicazione, spetta all'utente come integrare i risultati con la progettazione.In your application, it is up to you as to how you will integrate the results with your design. Questo corso è stato progettato per insegnare come integrare un servizio di Azure con il progetto Unity.This course is designed to teach you how to integrate an Azure Service with your Unity Project. Per migliorare l'applicazione di realtà mista, è compito dell'utente sfruttare le conoscenze acquisite in questo corso.It is your job to use the knowledge you gain from this course to enhance your mixed reality Application.

Supporto di dispositiviDevice support

CorsoCourse HoloLensHoloLens Visori VR immersiveImmersive headsets
MR e Azure 305: Funzioni e archiviazioneMR and Azure 305: Functions and storage ✔️✔️ ✔️✔️

Nota

Sebbene questo corso sia incentrato principalmente sugli auricolari per la realtà mista (VR) di Windows, è anche possibile applicare le informazioni apprese in questo corso a Microsoft HoloLens.While this course primarily focuses on Windows Mixed Reality immersive (VR) headsets, you can also apply what you learn in this course to Microsoft HoloLens. Seguendo le istruzioni riportate in questo corso, vengono visualizzate le note sulle eventuali modifiche che potrebbero essere necessarie per supportare HoloLens.As you follow along with the course, you will see notes on any changes you might need to employ to support HoloLens.

PrerequisitiPrerequisites

Nota

Questa esercitazione è progettata per gli sviluppatori che hanno esperienza di base con Unity e C#.This tutorial is designed for developers who have basic experience with Unity and C#. Tenere inoltre presente che i prerequisiti e le istruzioni scritte in questo documento rappresentano gli elementi testati e verificati al momento della stesura del documento (maggio 2018).Please also be aware that the prerequisites and written instructions within this document represent what has been tested and verified at the time of writing (May 2018). È possibile utilizzare il software più recente, come indicato nell'articolo installare gli strumenti , ma non si presuppone che le informazioni in questo corso corrispondano perfettamente a quelle disponibili nel software più recente rispetto a quanto indicato di seguito.You are free to use the latest software, as listed within the install the tools article, though it should not be assumed that the information in this course will perfectly match what you'll find in newer software than what's listed below.

Per questo corso è consigliabile usare i componenti hardware e software seguenti:We recommend the following hardware and software for this course:

Prima di iniziareBefore you start

Per evitare che si verifichino problemi durante la compilazione di questo progetto, è consigliabile creare il progetto indicato in questa esercitazione in una cartella radice o quasi radice (i percorsi di cartella lunghi possono causare problemi in fase di compilazione).To avoid encountering issues building this project, it is strongly suggested that you create the project mentioned in this tutorial in a root or near-root folder (long folder paths can cause issues at build-time).

Capitolo 1-portale di AzureChapter 1 - The Azure Portal

Per usare il servizio di archiviazione di Azure, è necessario creare e configurare un account di archiviazione nell'portale di Azure.To use the Azure Storage Service, you will need to create and configure a Storage Account in the Azure portal.

  1. Accedere al portale di Azure.Log in to the Azure Portal.

    Nota

    Se non si dispone già di un account Azure, sarà necessario crearne uno.If you do not already have an Azure account, you will need to create one. Se si segue questa esercitazione in una classe o in una situazione di laboratorio, rivolgersi all'insegnante o a uno dei Proctor per ottenere assistenza nella configurazione del nuovo account.If you are following this tutorial in a classroom or lab situation, ask your instructor or one of the proctors for help setting up your new account.

  2. Una volta effettuato l'accesso, fare clic su nuovo nell'angolo in alto a sinistra e cercare account di archiviazione e premere invio.Once you are logged in, click on New in the top left corner, and search for Storage account, and click Enter.

    ricerca di archiviazione di Azure

    Nota

    La parola New potrebbe essere stata sostituita con Crea una risorsa, nei portali più recenti.The word New may have been replaced with Create a resource, in newer portals.

  3. La nuova pagina fornirà una descrizione del servizio account di archiviazione di Azure .The new page will provide a description of the Azure Storage account service. Nella parte inferiore sinistra di questo prompt selezionare il pulsante Crea per creare un'associazione con il servizio.At the bottom left of this prompt, select the Create button, to create an association with this service.

    Crea servizio

  4. Una volta fatto clic su Crea:Once you have clicked on Create:

    1. Inserire un nome per l'account, tenere presente che questo campo accetta solo numeri e lettere minuscole.Insert a Name for your account, be aware this field only accepts numbers, and lowercase letters.

    2. Per modello di distribuzione selezionare Resource Manager.For Deployment model, select Resource manager.

    3. Per tipo di account selezionare archiviazione (utilizzo generico V1).For Account kind, select Storage (general purpose v1).

    4. Determinare il percorso del gruppo di risorse (se si sta creando un nuovo gruppo di risorse).Determine the Location for your resource group (if you are creating a new Resource Group). Il percorso dovrebbe trovarsi idealmente nell'area in cui verrà eseguita l'applicazione.The location would ideally be in the region where the application would run. Alcune risorse di Azure sono disponibili solo in determinate aree geografiche.Some Azure assets are only available in certain regions.

    5. Per la replica selezionare l'archiviazione con ridondanza geografica e accesso in lettura (RA-GRS).For Replication select Read-access-geo-redundant storage (RA-GRS).

    6. Per Prestazioni selezionare Standard.For Performance, select Standard.

    7. Lasciare il trasferimento sicuro necessario come disabilitato.Leave Secure transfer required as Disabled.

    8. Selezionare una Sottoscrizione.Select a Subscription.

    9. Scegliere un gruppo di risorse o crearne uno nuovo.Choose a Resource Group or create a new one. Un gruppo di risorse consente di monitorare, controllare l'accesso, effettuare il provisioning e gestire la fatturazione per una raccolta di asset di Azure.A resource group provides a way to monitor, control access, provision and manage billing for a collection of Azure assets. Si consiglia di lasciare tutti i servizi di Azure associati a un singolo progetto (ad esempio questi Lab) in un gruppo di risorse comune).It is recommended to keep all the Azure services associated with a single project (e.g. such as these labs) under a common resource group).

      Per altre informazioni sui gruppi di risorse di Azure, vedere l'articolo relativo al gruppo di risorse.If you wish to read more about Azure Resource Groups, please visit the resource group article.

    10. Sarà inoltre necessario confermare di aver compreso i termini e le condizioni applicati a questo servizio.You will also need to confirm that you have understood the Terms and Conditions applied to this Service.

    11. Selezionare Create (Crea).Select Create.

      informazioni sul servizio di input

  5. Una volta fatto clic su Crea, sarà necessario attendere il completamento della creazione del servizio. l'operazione potrebbe richiedere un minuto.Once you have clicked on Create, you will have to wait for the service to be created, this might take a minute.

  6. Dopo la creazione dell'istanza del servizio, verrà visualizzata una notifica nel portale.A notification will appear in the portal once the Service instance is created.

    nuova notifica nel portale di Azure

  7. Fare clic sulle notifiche per esplorare la nuova istanza del servizio.Click on the notifications to explore your new Service instance.

    Vai alla risorsa

  8. Fare clic sul pulsante Vai alla risorsa nella notifica per esplorare la nuova istanza del servizio.Click the Go to resource button in the notification to explore your new Service instance. Si verrà portati alla nuova istanza del servizio dell' account di archiviazione .You will be taken to your new Storage account service instance.

    chiavi di accesso

  9. Fare clic su chiavi di accesso per visualizzare gli endpoint per il servizio cloud.Click Access keys, to reveal the endpoints for this cloud service. Usare blocco note o simile per copiare una delle chiavi da usare in un secondo momento.Use Notepad or similar, to copy one of your keys for use later. Prendere nota anche del valore della stringa di connessione , che verrà usato nella classe Servizi , che verrà creata in un secondo momento.Also, note the Connection string value, as it will be used in the AzureServices class, which you will create later.

    copia stringa di connessione

Capitolo 2-configurazione di una funzione di AzureChapter 2 - Setting up an Azure Function

Verrà ora scritta una funzione di Azure nel servizio di Azure.You will now write an Azure Function in the Azure Service.

È possibile usare una funzione di Azure per eseguire quasi tutte le operazioni eseguite con una funzione classica nel codice. la differenza è che questa funzione è accessibile da qualsiasi applicazione con credenziali per accedere all'account di Azure.You can use an Azure Function to do nearly anything that you would do with a classic function in your code, the difference being that this function can be accessed by any application that has credentials to access your Azure Account.

Per creare una funzione di Azure:To create an Azure Function:

  1. Dal portale di Azure fare clic su nuovo nell'angolo in alto a sinistra e cercare app per le funzioni e premere invio.From your Azure Portal, click on New in the top left corner, and search for Function App, and click Enter.

    Crea app per le funzioni

    Nota

    La parola New potrebbe essere stata sostituita con Crea una risorsa, nei portali più recenti.The word New may have been replaced with Create a resource, in newer portals.

  2. La nuova pagina fornirà una descrizione del servizio app per le funzioni di Azure .The new page will provide a description of the Azure Function App service. Nella parte inferiore sinistra di questo prompt selezionare il pulsante Crea per creare un'associazione con il servizio.At the bottom left of this prompt, select the Create button, to create an association with this service.

    informazioni sull'app per le funzioni

  3. Una volta fatto clic su Crea:Once you have clicked on Create:

    1. Specificare un nome per l'app.Provide an App name. Qui è possibile usare solo lettere e numeri (maiuscole o minuscole).Only letters and numbers can be used here (either upper or lower case is allowed).

    2. Selezionare la sottoscrizione preferita.Select your preferred Subscription.

    3. Scegliere un gruppo di risorse o crearne uno nuovo.Choose a Resource Group or create a new one. Un gruppo di risorse consente di monitorare, controllare l'accesso, effettuare il provisioning e gestire la fatturazione per una raccolta di asset di Azure.A resource group provides a way to monitor, control access, provision and manage billing for a collection of Azure assets. Si consiglia di lasciare tutti i servizi di Azure associati a un singolo progetto (ad esempio questi Lab) in un gruppo di risorse comune).It is recommended to keep all the Azure services associated with a single project (e.g. such as these labs) under a common resource group).

      Per altre informazioni sui gruppi di risorse di Azure, vedere l'articolo relativo al gruppo di risorse.If you wish to read more about Azure Resource Groups, please visit the resource group article.

    4. Per questo esercizio, selezionare Windows come sistema operativo scelto.For this exercise, select Windows as the chosen OS.

    5. Selezionare il piano a consumo per il piano di hosting.Select Consumption Plan for the Hosting Plan.

    6. Determinare il percorso del gruppo di risorse (se si sta creando un nuovo gruppo di risorse).Determine the Location for your resource group (if you are creating a new Resource Group). Il percorso dovrebbe trovarsi idealmente nell'area in cui verrà eseguita l'applicazione.The location would ideally be in the region where the application would run. Alcune risorse di Azure sono disponibili solo in determinate aree geografiche.Some Azure assets are only available in certain regions. Per prestazioni ottimali, selezionare la stessa area dell'account di archiviazione.For optimal performance, select the same region as the storage account.

    7. Per archiviazione, selezionare Usa esistente e quindi usare il menu a discesa per individuare l'archiviazione creata in precedenza.For Storage, select Use existing, and then using the dropdown menu, find your previously created storage.

    8. Uscire da Application Insights per questo esercizio.Leave Application Insights off for this exercise.

      dettagli dell'app per le funzioni di input

  4. Fare clic sul pulsante Create (Crea).Click the Create button.

  5. Una volta fatto clic su Crea, sarà necessario attendere il completamento della creazione del servizio. l'operazione potrebbe richiedere un minuto.Once you have clicked on Create, you will have to wait for the service to be created, this might take a minute.

  6. Dopo la creazione dell'istanza del servizio, verrà visualizzata una notifica nel portale.A notification will appear in the portal once the Service instance is created.

    notifica del nuovo portale di Azure

  7. Fare clic sulle notifiche per esplorare la nuova istanza del servizio.Click on the notifications to explore your new Service instance.

    passa all'app per le funzioni delle risorse

  8. Fare clic sul pulsante Vai alla risorsa nella notifica per esplorare la nuova istanza del servizio.Click the Go to resource button in the notification to explore your new Service instance. Si verrà portati alla nuova istanza del servizio app per le funzioni .You will be taken to your new Function App service instance.

  9. Nel dashboard app per le funzioni , posizionare il puntatore del mouse sulle funzioni, disponibili all'interno del pannello a sinistra, quindi fare clic sul simbolo + (segno più) .On the Function App dashboard, hover your mouse over Functions, found within the panel on the left, and then click the + (plus) symbol.

    Crea nuova funzione

  10. Nella pagina successiva assicurarsi che webhook e l'API siano selezionati e per scegliere una lingua Selezionare CSharp, in quanto si tratta della lingua usata per questa esercitazione.On the next page, ensure Webhook + API is selected, and for Choose a language, select CSharp, as this will be the language used for this tutorial. Infine, fare clic sul pulsante Crea funzione .Lastly, click the Create this function button.

    Seleziona CSharp Web Hook

  11. È necessario passare alla tabella codici (Run. CSX), se non è possibile fare clic sulla funzione appena creata nell'elenco funzioni all'interno del pannello a sinistra.You should be taken to the code page (run.csx), if not though, click on the newly created Function in the Functions list within the panel on the left.

    Apri nuova funzione

  12. Copiare il codice seguente nella funzione.Copy the following code into your function. Questa funzione restituirà semplicemente un intero casuale compreso tra 0 e 2 quando viene chiamato.This function will simply return a random integer between 0 and 2 when called. Non preoccuparti del codice esistente, è possibile incollarlo nella parte superiore.Do not worry about the existing code, feel free to paste over the top of it.

        using System.Net;
        using System.Threading.Tasks;
    
        public static int Run(CustomObject req, TraceWriter log)
        {
            Random rnd = new Random();
            int randomInt = rnd.Next(0, 3);
            return randomInt;
        }
    
        public class CustomObject
        {
            public String name {get; set;}
        }
    
  13. Selezionare Salva.Select Save.

  14. Il risultato dovrebbe essere simile all'immagine seguente.The result should look like the image below.

  15. Fare clic su Ottieni URL funzione e prendere nota dell' endpoint visualizzato.Click on Get function URL and take note of the endpoint displayed. Sarà necessario inserirlo nella classe Servizi che verrà creata più avanti in questo corso.You will need to insert it into the AzureServices class that you will create later in this course.

    Ottieni endpoint funzione

    Inserisci endpoint funzione

Capitolo 3-configurazione del progetto UnityChapter 3 - Setting up the Unity project

Di seguito è riportata una configurazione tipica per lo sviluppo con realtà mista e, di conseguenza, un modello valido per altri progetti.The following is a typical set up for developing with Mixed Reality, and as such, is a good template for other projects.

Configurare e testare l'auricolare immersiva della realtà mista.Set up and test your mixed reality immersive headset.

Nota

Non sarà necessario alcun controller di movimento per questo corso.You will not require Motion Controllers for this course. Se è necessario supporto per la configurazione dell'auricolare immersivo, vedere l'articolo relativo alla configurazione della realtà mista.If you need support setting up the immersive headset, please visit the mixed reality set up article.

  1. Aprire Unity e fare clic su New.Open Unity and click New.

    Crea nuovo progetto Unity

  2. A questo punto sarà necessario specificare un nome di progetto Unity.You will now need to provide a Unity Project name. Inserire MR_Azure_Functions.Insert MR_Azure_Functions. Verificare che il tipo di progetto sia impostato su 3D.Make sure the project type is set to 3D. Impostare il percorso su un punto appropriato (ricordare che più vicino alle directory radice è migliore).Set the Location to somewhere appropriate for you (remember, closer to root directories is better). Fare quindi clic su Crea progetto.Then, click Create project.

    Assegnare un nome al nuovo progetto Unity

  3. Con Unity aperto, vale la pena controllare che l' editor di script predefinito sia impostato su Visual Studio.With Unity open, it is worth checking the default Script Editor is set to Visual Studio. Passare a modifica > Preferenze e quindi dalla nuova finestra passare a strumenti esterni.Go to Edit > Preferences and then from the new window, navigate to External Tools. Modificare l' editor di script esterno in Visual Studio 2017.Change External Script Editor to Visual Studio 2017. Chiudere la finestra delle Preferenze .Close the Preferences window.

    imposta Visual Studio come editor di script

  4. Passare quindi a > impostazioni di compilazione file e passare alla piattaforma piattaforma UWP (Universal Windows Platform), facendo clic sul pulsante Switch Platform .Next, go to File > Build Settings and switch the platform to Universal Windows Platform, by clicking on the Switch Platform button.

    passa alla piattaforma UWP

  5. Passare a > impostazioni di compilazione file e verificare che:Go to File > Build Settings and make sure that:

    1. Il dispositivo di destinazione è impostato su qualsiasi dispositivo.Target Device is set to Any Device.

      Per Microsoft HoloLens, impostare dispositivo di destinazione su HoloLens.For Microsoft HoloLens, set Target Device to HoloLens.

    2. Il tipo di compilazione è impostato su D3DBuild Type is set to D3D

    3. SDK è impostato sull' ultima versione installataSDK is set to Latest installed

    4. La versione di Visual Studio è impostata su installazione più recenteVisual Studio Version is set to Latest installed

    5. Compilazione ed esecuzione è impostato su computer localeBuild and Run is set to Local Machine

    6. Salvare la scena e aggiungerla alla compilazione.Save the scene and add it to the build.

      1. A tale scopo, selezionare Aggiungi scene aperte.Do this by selecting Add Open Scenes. Verrà visualizzata una finestra Salva.A save window will appear.

        Aggiungi scene aperte

      2. Creare una nuova cartella per questo e per eventuali scenari futuri, quindi selezionare il pulsante nuova cartella per creare una nuova cartella , assegnarle un nome.Create a new folder for this, and any future, scene, then select the New folder button, to create a new folder, name it Scenes.

        cartella crea scene

      3. Aprire la cartella Scenes appena creata e quindi nel campo nome file: testo digitare FunctionsScene e quindi fare clic su Salva.Open your newly created Scenes folder, and then in the File name: text field, type FunctionsScene, then press Save.

        Scena Salva funzioni

  6. Le impostazioni rimanenti, nelle impostazioni di compilazione, devono essere lasciate come predefinite per il momento.The remaining settings, in Build Settings, should be left as default for now.

    Lascia impostazioni di compilazione predefinite

  7. Nella finestra impostazioni di compilazione fare clic sul pulsante Impostazioni lettore . verrà aperto il pannello correlato nello spazio in cui si trova il controllo .In the Build Settings window, click on the Player Settings button, this will open the related panel in the space where the Inspector is located.

    impostazioni del lettore in Inspector

  8. In questo pannello è necessario verificare alcune impostazioni:In this panel, a few settings need to be verified:

    1. Nella scheda altre impostazioni :In the Other Settings tab:

      1. La versione di runtime di scripting deve essere sperimentale (equivalente a .NET 4,6), che attiverà la necessità di riavviare l'editor.Scripting Runtime Version should be Experimental (.NET 4.6 Equivalent), which will trigger a need to restart the Editor.
      2. Il back-end di scripting deve essere .NETScripting Backend should be .NET
      3. Il livello di compatibilità API deve essere .NET 4,6API Compatibility Level should be .NET 4.6
    2. Nella scheda impostazioni di pubblicazione , in funzionalità, selezionare:Within the Publishing Settings tab, under Capabilities, check:

      • InternetClientInternetClient

        impostare le funzionalità

    3. Nella parte inferiore del pannello, nelle impostazioni di XR (disponibili sotto le impostazioni di pubblicazione), verificare la realtà virtuale supportata, verificare che sia stato aggiunto Windows Mixed Reality SDK .Further down the panel, in XR Settings (found below Publishing Settings), tick Virtual Reality Supported, make sure the Windows Mixed Reality SDK is added.

      impostare le impostazioni di XR

  9. Nelle impostazioni di compilazione i progetti C# non sono più disattivati; Selezionare la casella di controllo accanto a questo.Back in Build Settings Unity C# Projects is no longer greyed out; tick the checkbox next to this.

    Seleziona progetti c#

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

  11. Salva la scena e il progetto (progetto Salva > scena/ > Salva file).Save your Scene and Project (FILE > SAVE SCENE / FILE > SAVE PROJECT).

Capitolo 4-installazione della fotocamera principaleChapter 4 - Setup Main Camera

Importante

Se si vuole ignorare i componenti di configurazione di Unity di questo corso e continuare direttamente con il codice, è possibile scaricare questo. file unitypackage Toolse importarlo nel progetto come pacchetto personalizzato.If you wish to skip the Unity Set up components of this course, and continue straight into code, feel free to download this .unitypackage, and import it into your project as a Custom Package. Questo conterrà anche le dll del capitolo successivo.This will also contain the DLLs from the next Chapter. Dopo l'importazione, continuare con il capitolo 7.After import, continue from Chapter 7.

  1. Nel Pannello gerarchia è presente un oggetto denominato Main camera, che rappresenta il punto di visualizzazione "Head" dopo che l'applicazione è stata "interna".In the Hierarchy Panel, you will find an object called Main Camera, this object represents your "head" point of view once you are "inside" your application.

  2. Con il dashboard Unity in primo piano, selezionare la fotocamera principale GameObject.With the Unity Dashboard in front of you, select the Main Camera GameObject. Si noterà che il pannello Inspector , disponibile in genere a destra, all'interno del dashboard, visualizzerà i vari componenti di tale GameObject, con la trasformazione nella parte superiore, seguita dalla fotocamera e da altri componenti.You will notice that the Inspector Panel (generally found to the right, within the Dashboard) will show the various components of that GameObject, with Transform at the top, followed by Camera, and some other components. Sarà necessario reimpostare la trasformazione della fotocamera principale, in modo che venga posizionata correttamente.You will need to reset the Transform of the Main Camera, so it is positioned correctly.

  3. A tale scopo, selezionare l'icona dell' ingranaggio accanto al componente trasformazione della fotocamera e selezionare Reimposta.To do this, select the Gear icon next to the Camera's Transform component, and select Reset.

    Reimposta trasformazione

  4. Aggiornare quindi il componente Transform in modo simile al seguente:Then update the Transform component to look like:

    TRASFORMAZIONE-POSIZIONETRANSFORM - POSITION
    XX SY ZZ
    00 11 00
    TRASFORMAZIONE-ROTAZIONETRANSFORM - ROTATION
    XX SY ZZ
    00 00 00
    TRASFORMAZIONE-RIDIMENSIONATRANSFORM - SCALE
    XX SY ZZ
    11 11 11

    imposta trasformazione fotocamera

Capitolo 5-configurazione della scena UnityChapter 5 - Setting up the Unity scene

  1. Fare clic con il pulsante destro del mouse in un'area vuota del Pannello gerarchia, sotto oggetto 3D, Aggiungi un piano.Right-click in an empty area of the Hierarchy Panel, under 3D Object, add a Plane.

    Crea nuovo piano

  2. Con l'oggetto piano selezionato, modificare i parametri seguenti nel Pannello di controllo:With the Plane object selected, change the following parameters in the Inspector Panel:

    TRASFORMAZIONE-POSIZIONETRANSFORM - POSITION
    XX SY ZZ
    00 00 44
    TRASFORMAZIONE-RIDIMENSIONATRANSFORM - SCALE
    XX SY ZZ
    1010 11 1010

    Imposta posizione e scala del piano

    visualizzazione scena del piano

  3. Fare clic con il pulsante destro del mouse in un'area vuota del Pannello gerarchia, sotto oggetto 3D, Aggiungi un cubo.Right-click in an empty area of the Hierarchy Panel, under 3D Object, add a Cube.

    1. Rinominare il cubo in GazeButton (con il cubo selezionato, premere ' F2').Rename the Cube to GazeButton (with the Cube selected, press 'F2').

    2. Modificare i parametri seguenti nel Pannello di controllo:Change the following parameters in the Inspector Panel:

      TRASFORMAZIONE-POSIZIONETRANSFORM - POSITION
      XX SY ZZ
      00 33 55

      imposta la trasformazione del pulsante di sguardo

      visualizzazione della scena del pulsante Guarda

    3. Fare clic sul pulsante a discesa tag e fare clic su Aggiungi tag per aprire il riquadro Tag & livelli.Click on the Tag drop-down button and click on Add Tag to open the Tags & Layers Pane.

      Aggiungi nuovo tag

      Seleziona più

    4. Selezionare il pulsante + (segno più) e nel campo nuovo nome tag immettere GazeButton e quindi fare clic su Salva.Select the + (plus) button, and in the New Tag Name field, enter GazeButton, and press Save.

      nome nuovo tag

    5. Fare clic sull'oggetto GazeButton nel Pannello gerarchia e nel pannello Inspector assegnare il tag GazeButton appena creato.Click on the GazeButton object in the Hierarchy Panel, and in the Inspector Panel, assign the newly created GazeButton tag.

      pulsante assegna sguardo al nuovo tag

  4. Fare clic con il pulsante destro del mouse sull'oggetto GazeButton , nel Pannello gerarchia e aggiungere un GameObject vuoto (che verrà aggiunto come oggetto figlio ).Right-click on the GazeButton object, in the Hierarchy Panel, and add an Empty GameObject (which will be added as a child object).

  5. Selezionare il nuovo oggetto e rinominarlo ShapeSpawnPoint.Select the new object and rename it ShapeSpawnPoint.

    1. Modificare i parametri seguenti nel Pannello di controllo:Change the following parameters in the Inspector Panel:

      TRASFORMAZIONE-POSIZIONETRANSFORM - POSITION
      XX SY ZZ
      00 -1-1 00

      Aggiorna trasformazione punto di generazione forma

      visualizzazione scena punto di generazione forma

  6. Successivamente verrà creato un oggetto testo 3D per fornire commenti e suggerimenti sullo stato del servizio di Azure.Next you will create a 3D Text object to provide feedback on the status of the Azure service.

    Fare di nuovo clic con il pulsante destro del mouse su GazeButton nel pannello gerarchia e aggiungere un oggetto 3D oggetto > testo 3D come elemento figlio.Right click on the GazeButton in the Hierarchy Panel again and add a 3D Object > 3D Text object as a child.

    Crea nuovo oggetto testo 3D

  7. Rinominare l'oggetto testo 3D in AzureStatusText.Rename the 3D Text object to AzureStatusText.

  8. Modificare la trasformazione dell'oggetto AzureStatusText nel modo seguente:Change the AzureStatusText object Transform as follows:

    TRASFORMAZIONE-POSIZIONETRANSFORM - POSITION
    XX SY ZZ
    00 00 -0,6-0.6
    TRASFORMAZIONE-RIDIMENSIONATRANSFORM - SCALE
    XX SY ZZ
    0,10.1 0,10.1 0,10.1

    Nota

    Non preoccuparti se sembra essere fuori sede, perché verrà corretto quando il componente mesh del testo seguente viene aggiornato.Do not worry if it appears to be off-centre, as this will be fixed when the below Text Mesh component is updated.

  9. Modificare il componente mesh di testo in modo che corrisponda a quanto segue:Change the Text Mesh component to match the below:

    imposta componente mesh testo

    Suggerimento

    Il colore selezionato è il colore esadecimale: 000000FF, sebbene sia possibile sceglierne un altro, è sufficiente assicurarsi che sia leggibile.The selected color here is Hex color: 000000FF, though feel free to choose your own, just ensure it is readable.

  10. La struttura del pannello della gerarchia dovrebbe ora essere simile alla seguente:Your Hierarchy Panel structure should now look like this:

    Mesh di testo nella gerarchia

  11. La scena dovrebbe ora essere simile alla seguente:Your scene should now look like this:

    Mesh di testo in visualizzazione scena

Capitolo 6: importare archiviazione di Azure per UnityChapter 6 - Import Azure Storage for Unity

Si utilizzerà archiviazione di Azure per Unity (che a sua volta USA .NET SDK per Azure).You will be using Azure Storage for Unity (which itself leverages the .Net SDK for Azure). Per altre informazioni, vedere l' articolo archiviazione di Azure per Unity.You can read more about this at the Azure Storage for Unity article.

Attualmente esiste un problema noto in Unity che richiede che i plug-in vengano riconfigurati dopo l'importazione.There is currently a known issue in Unity which requires plugins to be reconfigured after import. Questi passaggi (4-7 in questa sezione) non saranno più necessari dopo la risoluzione del bug.These steps (4 - 7 in this section) will no longer be required after the bug has been resolved.

Per importare l'SDK nel progetto, assicurarsi di aver scaricato la versione più recente di ". file unitypackage Tools" da GitHub.To import the SDK into your own project, make sure you have downloaded the latest '.unitypackage' from GitHub. Procedere quindi come segue:Then, do the following:

  1. Aggiungere il file con estensione file unitypackage Tools a Unity usando l'opzione di menu Asset > Import Package > Custom Package .Add the .unitypackage file to Unity by using the Assets > Import Package > Custom Package menu option.

  2. Nella casella Importa pacchetto Unity visualizzata è possibile selezionare tutti gli elementi in archiviazione plug-in > .In the Import Unity Package box that pops up, you can select everything under Plugin > Storage. Deselezionare tutti gli altri elementi, perché non sono necessari per questo corso.Uncheck everything else, as it is not needed for this course.

    Importa nel pacchetto

  3. Fare clic sul pulsante Importa per aggiungere gli elementi al progetto.Click the Import button to add the items to your project.

  4. Passare alla cartella archiviazione in plug-in, nella visualizzazione del progetto e selezionare solo i plug-in seguenti:Go to the Storage folder under Plugins, in the Project view, and select the following plugins only:

    • Microsoft.Data.EdmMicrosoft.Data.Edm

    • Microsoft.Data.ODataMicrosoft.Data.OData

    • Microsoft.WindowsAzure.StorageMicrosoft.WindowsAzure.Storage

    • Newtonsoft.JsonNewtonsoft.Json

    • System.SpatialSystem.Spatial

      deseleziona qualsiasi piattaforma

  5. Con questi plug -in specifici selezionati, deselezionare qualsiasi piattaforma e deselezionare WSAPlayer , quindi fare clic su applica.With these specific plugins selected, uncheck Any Platform and uncheck WSAPlayer then click Apply.

    applica dll della piattaforma

    Nota

    Questi specifici plug-in vengono contrassegnati per essere usati solo nell'editor di Unity.We are marking these particular plugins to only be used in the Unity Editor. Questo è dovuto al fatto che esistono versioni diverse degli stessi plug-in nella cartella WSA che verranno usate dopo l'esportazione del progetto da Unity.This is because there are different versions of the same plugins in the WSA folder that will be used after the project is exported from Unity.

  6. Nella cartella plugin di archiviazione selezionare solo:In the Storage plugin folder, select only:

    • Microsoft.Data.Services.ClientMicrosoft.Data.Services.Client

      impostazione non elabora per le dll

  7. Selezionare la casella non elaborare in Impostazioni piattaforma e fare clic su applica.Check the Don't Process box under Platform Settings and click Apply.

    non applicare alcuna elaborazione

    Nota

    Si sta contrassegnando questo plug-in "non elaborare" perché il plug-in assembly Unity ha difficoltà nell'elaborare questo plug-in.We are marking this plugin "Don't process" because the Unity assembly patcher has difficulty processing this plugin. Il plug-in continuerà a funzionare anche se non viene elaborato.The plugin will still work even though it is not processed.

Capitolo 7: creare la classe serviziChapter 7 - Create the AzureServices class

La prima classe che si intende creare è la classe Servizi .The first class you are going to create is the AzureServices class.

La classe Servizi sarà responsabile di:The AzureServices class will be responsible for:

  • Archiviazione delle credenziali dell'account Azure.Storing Azure Account credentials.

  • Chiamata della funzione app Azure.Calling your Azure App Function.

  • Caricare e scaricare il file di dati nella risorsa di archiviazione cloud di Azure.The upload and download of the data file in your Azure Cloud Storage.

Per creare questa classe:To create this Class:

  1. Fare clic con il pulsante destro del mouse nella cartella Asset , che si trova nel pannello progetto, Crea > cartella.Right-click in the Asset Folder, located in the Project Panel, Create > Folder. Denominare gli script della cartella.Name the folder Scripts.

    Crea nuova cartella

    cartella di chiamata-script

  2. Fare doppio clic sulla cartella appena creata per aprirla.Double click on the folder just created, to open it.

  3. Fare clic con il pulsante destro del mouse all'interno della cartella e creare > uno script C#.Right-click inside the folder, Create > C# Script. Chiamare lo script Servizi.Call the script AzureServices.

  4. Fare doppio clic sulla nuova classe Servizi per aprirla con Visual Studio.Double click on the new AzureServices class to open it with Visual Studio.

  5. Aggiungere gli spazi dei nomi seguenti all'inizio di Servizi:Add the following namespaces to the top of the AzureServices:

        using System;
        using System.Threading.Tasks;
        using UnityEngine;
        using Microsoft.WindowsAzure.Storage;
        using Microsoft.WindowsAzure.Storage.File;
        using System.IO;
        using System.Net;
    
  6. Aggiungere i campi Inspector seguenti all'interno della classe Servizi :Add the following Inspector Fields inside the AzureServices class:

        /// <summary>
        /// Provides Singleton-like behavior to this class.
        /// </summary>
        public static AzureServices instance;
    
        /// <summary>
        /// Reference Target for AzureStatusText Text Mesh object
        /// </summary>
        public TextMesh azureStatusText;
    
  7. Aggiungere quindi le variabili membro seguenti all'interno della classe Servizi :Then add the following member variables inside the AzureServices class:

        /// <summary>
        /// Holds the Azure Function endpoint - Insert your Azure Function
        /// Connection String here.
        /// </summary>
    
        private readonly string azureFunctionEndpoint = "--Insert here you AzureFunction Endpoint--";
    
        /// <summary>
        /// Holds the Storage Connection String - Insert your Azure Storage
        /// Connection String here.
        /// </summary>
        private readonly string storageConnectionString = "--Insert here you AzureStorage Connection String--";
    
        /// <summary>
        /// Name of the Cloud Share - Hosts directories.
        /// </summary>
        private const string fileShare = "fileshare";
    
        /// <summary>
        /// Name of a Directory within the Share
        /// </summary>
        private const string storageDirectory = "storagedirectory";
    
        /// <summary>
        /// The Cloud File
        /// </summary>
        private CloudFile shapeIndexCloudFile;
    
        /// <summary>
        /// The Linked Storage Account
        /// </summary>
        private CloudStorageAccount storageAccount;
    
        /// <summary>
        /// The Cloud Client
        /// </summary>
        private CloudFileClient fileClient;
    
        /// <summary>
        /// The Cloud Share - Hosts Directories
        /// </summary>
        private CloudFileShare share;
    
        /// <summary>
        /// The Directory in the share that will host the Cloud file
        /// </summary>
        private CloudFileDirectory dir;
    

    Importante

    Assicurarsi di sostituire i valori della stringa di connessione e dell' endpoint con i valori di archiviazione di Azure, disponibili nel portale di AzureMake sure you replace the endpoint and connection string values with the values from your Azure storage, found in the Azure Portal

  8. È ora necessario aggiungere il codice per i metodi svegli () e Start () .Code for Awake() and Start() methods now needs to be added. Questi metodi verranno chiamati quando la classe inizializza:These methods will be called when the class initializes:

        private void Awake()
        {
            instance = this;
        }
    
        // Use this for initialization
        private void Start()
        {
            // Set the Status text to loading, whilst attempting connection to Azure.
            azureStatusText.text = "Loading...";
        }
    
        /// <summary>
        /// Call to the Azure Function App to request a Shape.
        /// </summary>
        public async void CallAzureFunctionForNextShape()
        {
    
        }
    

    Importante

    Il codice per CallAzureFunctionForNextShape () viene compilato in un capitolo futuro.We will fill in the code for CallAzureFunctionForNextShape() in a future Chapter.

  9. Eliminare il metodo Update () perché non verrà utilizzato da questa classe.Delete the Update() method since this class will not use it.

  10. Salvare le modifiche in Visual Studio e quindi tornare a Unity.Save your changes in Visual Studio, and then return to Unity.

  11. Fare clic e trascinare la classe Servizi dalla cartella Scripts all'oggetto principale della fotocamera nel Pannello gerarchia.Click and drag the AzureServices class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

  12. Selezionare la fotocamera principale, quindi estrarre l'oggetto figlio AzureStatusText dall'oggetto GazeButton e inserirlo nel campo destinazione riferimento AzureStatusText , nel controllo, per fornire il riferimento allo script Servizi .Select the Main Camera, then grab the AzureStatusText child object from beneath the GazeButton object, and place it within the AzureStatusText reference target field, in the Inspector, to provide the reference to the AzureServices script.

    assegnare la destinazione di riferimento del testo di stato di Azure

Capitolo 8: creare la classe ShapeFactoryChapter 8 - Create the ShapeFactory class

Lo script successivo da creare è la classe ShapeFactory .The next script to create, is the ShapeFactory class. Il ruolo di questa classe è creare una nuova forma, quando richiesto, e conservarne una cronologia delle forme create in un elenco della cronologia delle forme.The role of this class is to create a new shape, when requested, and keep a history of the shapes created in a Shape History List. Ogni volta che viene creata una forma, l' elenco della cronologia delle forme viene aggiornato nella classe AzureService e quindi archiviato in archiviazione di Azure.Every time a shape is created, the Shape History list is updated in the AzureService class, and then stored in your Azure Storage. All'avvio dell'applicazione, se viene trovato un file archiviato in archiviazione di Azure, l' elenco della cronologia delle forme viene recuperato e riprodotto, con l'oggetto testo 3D che indica se la forma generata è di archiviazione o una nuova.When the application starts, if a stored file is found in your Azure Storage, the Shape History list is retrieved and replayed, with the 3D Text object providing whether the generated shape is from storage, or new.

Per creare questa classe:To create this class:

  1. Passare alla cartella Scripts creata in precedenza.Go to the Scripts folder you created previously.

  2. Fare clic con il pulsante destro del mouse all'interno della cartella e creare > uno script C#.Right-click inside the folder, Create > C# Script. Chiamare lo script ShapeFactory.Call the script ShapeFactory.

  3. Fare doppio clic sul nuovo script ShapeFactory per aprirlo con Visual Studio.Double click on the new ShapeFactory script to open it with Visual Studio.

  4. Verificare che la classe ShapeFactory includa gli spazi dei nomi seguenti:Ensure the ShapeFactory class includes the following namespaces:

        using System.Collections.Generic;
        using UnityEngine;
    
  5. Aggiungere le variabili illustrate di seguito alla classe ShapeFactory e sostituire le funzioni Start () e svegli () con quelle riportate di seguito:Add the variables shown below to the ShapeFactory class, and replace the Start() and Awake() functions with those below:

        /// <summary>
        /// Provide this class Singleton-like behaviour
        /// </summary>
        [HideInInspector]
        public static ShapeFactory instance;
    
        /// <summary>
        /// Provides an Inspector exposed reference to ShapeSpawnPoint
        /// </summary>
        [SerializeField]
        public Transform spawnPoint;
    
        /// <summary>
        /// Shape History Index
        /// </summary>
        [HideInInspector]
        public List<int> shapeHistoryList;
    
        /// <summary>
        /// Shapes Enum for selecting required shape
        /// </summary>
        private enum Shapes { Cube, Sphere, Cylinder }
    
        private void Awake()
        {
            instance = this;
        }
    
        private void Start()
        {
            shapeHistoryList = new List<int>();
        }
    
  6. Il metodo createShape () genera le forme primitive, in base al parametro Integer fornito.The CreateShape() method generates the primitive shapes, based upon the provided integer parameter. Il parametro booleano viene usato per specificare se la forma attualmente creata è di archiviazione o nuova.The Boolean parameter is used to specify whether the currently created shape is from storage, or new. Inserire il codice seguente nella classe ShapeFactory , sotto i metodi precedenti:Place the following code in your ShapeFactory class, below the previous methods:

        /// <summary>
        /// Use the Shape Enum to spawn a new Primitive object in the scene
        /// </summary>
        /// <param name="shape">Enumerator Number for Shape</param>
        /// <param name="storageShape">Provides whether this is new or old</param>
        internal void CreateShape(int shape, bool storageSpace)
        {
            Shapes primitive = (Shapes)shape;
            GameObject newObject = null;
            string shapeText = storageSpace == true ? "Storage: " : "New: ";
    
            AzureServices.instance.azureStatusText.text = string.Format("{0}{1}", shapeText, primitive.ToString());
    
            switch (primitive)
            {
                case Shapes.Cube:
                newObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
                break;
    
                case Shapes.Sphere:
                newObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                break;
    
                case Shapes.Cylinder:
                newObject = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                break;
            }
    
            if (newObject != null)
            {
                newObject.transform.position = spawnPoint.position;
    
                newObject.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
    
                newObject.AddComponent<Rigidbody>().useGravity = true;
    
                newObject.GetComponent<Renderer>().material.color = UnityEngine.Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f);
            }
        }
    
  7. Assicurarsi di salvare le modifiche in Visual Studio prima di tornare a Unity.Be sure to save your changes in Visual Studio before returning to Unity.

  8. Nell'editor di Unity fare clic e trascinare la classe ShapeFactory dalla cartella Scripts all'oggetto principale della fotocamera nel Pannello gerarchia.Back in the Unity Editor, click and drag the ShapeFactory class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

  9. Con la fotocamera principale selezionata, si noterà che nel componente di script ShapeFactory manca il riferimento al punto di generazione .With the Main Camera selected you will notice the ShapeFactory script component is missing the Spawn Point reference. Per risolvere il problema, trascinare l'oggetto ShapeSpawnPoint dal Pannello gerarchia alla destinazione di riferimento del punto di generazione .To fix it, drag the ShapeSpawnPoint object from the Hierarchy Panel to the Spawn Point reference target.

    imposta la destinazione del riferimento alla Factory della forma

Capitolo 9: creare la classe sguardiChapter 9 - Create the Gaze class

L'ultimo script che è necessario creare è la classe sguardi .The last script you need to create is the Gaze class.

Questa classe è responsabile della creazione di un Raycast che verrà proiettato in futuro dalla fotocamera principale, per individuare l'oggetto analizzato dall'utente.This class is responsible for creating a Raycast that will be projected forward from the Main Camera, to detect which object the user is looking at. In questo caso, Raycast dovrà identificare se l'utente sta esaminando l'oggetto GazeButton nella scena e attivare un comportamento.In this case, the Raycast will need to identify if the user is looking at the GazeButton object in the scene and trigger a behavior.

Per creare questa classe:To create this Class:

  1. Passare alla cartella Scripts creata in precedenza.Go to the Scripts folder you created previously.

  2. Fare clic con il pulsante destro del mouse nel pannello progetto, quindi creare > uno script C#.Right-click in the Project Panel, Create > C# Script. Chiamare lo sguardo dello script.Call the script Gaze.

  3. Fare doppio clic sul nuovo script per aprirlo con Visual Studio.Double click on the new Gaze script to open it with Visual Studio.

  4. Verificare che nella parte superiore dello script sia incluso lo spazio dei nomi seguente:Ensure the following namespace is included at the top of the script:

        using UnityEngine;
    
  5. Aggiungere quindi le variabili seguenti all'interno della classe sguardi :Then add the following variables inside the Gaze class:

        /// <summary>
        /// Provides Singleton-like behavior to this class.
        /// </summary>
        public static Gaze instance;
    
        /// <summary>
        /// The Tag which the Gaze will use to interact with objects. Can also be set in editor.
        /// </summary>
        public string InteractibleTag = "GazeButton";
    
        /// <summary>
        /// The layer which will be detected by the Gaze ('~0' equals everything).
        /// </summary>
        public LayerMask LayerMask = ~0;
    
        /// <summary>
        /// The Max Distance the gaze should travel, if it has not hit anything.
        /// </summary>
        public float GazeMaxDistance = 300;
    
        /// <summary>
        /// The size of the cursor, which will be created.
        /// </summary>
        public Vector3 CursorSize = new Vector3(0.05f, 0.05f, 0.05f);
    
        /// <summary>
        /// The color of the cursor - can be set in editor.
        /// </summary>
        public Color CursorColour = Color.HSVToRGB(0.0223f, 0.7922f, 1.000f);
    
        /// <summary>
        /// Provides when the gaze is ready to start working (based upon whether
        /// Azure connects successfully).
        /// </summary>
        internal bool GazeEnabled = false;
    
        /// <summary>
        /// The currently focused object.
        /// </summary>
        internal GameObject FocusedObject { get; private set; }
    
        /// <summary>
        /// The object which was last focused on.
        /// </summary>
        internal GameObject _oldFocusedObject { get; private set; }
    
        /// <summary>
        /// The info taken from the last hit.
        /// </summary>
        internal RaycastHit HitInfo { get; private set; }
    
        /// <summary>
        /// The cursor object.
        /// </summary>
        internal GameObject Cursor { get; private set; }
    
        /// <summary>
        /// Provides whether the raycast has hit something.
        /// </summary>
        internal bool Hit { get; private set; }
    
        /// <summary>
        /// This will store the position which the ray last hit.
        /// </summary>
        internal Vector3 Position { get; private set; }
    
        /// <summary>
        /// This will store the normal, of the ray from its last hit.
        /// </summary>
        internal Vector3 Normal { get; private set; }
    
        /// <summary>
        /// The start point of the gaze ray cast.
        /// </summary>
        private Vector3 _gazeOrigin;
    
        /// <summary>
        /// The direction in which the gaze should be.
        /// </summary>
        private Vector3 _gazeDirection;
    

Importante

Alcune di queste variabili possono essere modificate nell' Editor.Some of these variables will be able to be edited in the Editor.

  1. È ora necessario aggiungere il codice per i metodi svegli () e Start () .Code for the Awake() and Start() methods now needs to be added.

        /// <summary>
        /// The method used after initialization of the scene, though before Start().
        /// </summary>
        private void Awake()
        {
            // Set this class to behave similar to singleton
            instance = this;
        }
    
        /// <summary>
        /// Start method used upon initialization.
        /// </summary>
        private void Start()
        {
            FocusedObject = null;
            Cursor = CreateCursor();
        }
    
  2. Aggiungere il codice seguente, in cui verrà creato un oggetto cursore all'inizio, insieme al metodo Update () , che eseguirà il metodo Raycast, insieme alla posizione in cui viene attivato il valore booleano GazeEnabled:Add the following code, which will create a cursor object at start, along with the Update() method, which will run the Raycast method, along with being where the GazeEnabled boolean is toggled:

        /// <summary>
        /// Method to create a cursor object.
        /// </summary>
        /// <returns></returns>
        private GameObject CreateCursor()
        {
            GameObject newCursor = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            newCursor.SetActive(false);
    
            // Remove the collider, so it doesn't block raycast.
            Destroy(newCursor.GetComponent<SphereCollider>());
            newCursor.transform.localScale = CursorSize;
    
            newCursor.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Diffuse"))
            {
                color = CursorColour
            };
    
            newCursor.name = "Cursor";
    
            newCursor.SetActive(true);
    
            return newCursor;
        }
    
        /// <summary>
        /// Called every frame
        /// </summary>
        private void Update()
        {
            if(GazeEnabled == true)
            {
                _gazeOrigin = Camera.main.transform.position;
    
                _gazeDirection = Camera.main.transform.forward;
    
                UpdateRaycast();
            }
        }
    
  3. Aggiungere quindi il metodo UpdateRaycast () che proietta un Raycast e rileva la destinazione dell'hit.Next add the UpdateRaycast() method, which will project a Raycast and detect the hit target.

        private void UpdateRaycast()
        {
            // Set the old focused gameobject.
            _oldFocusedObject = FocusedObject;
    
            RaycastHit hitInfo;
    
            // Initialise Raycasting.
            Hit = Physics.Raycast(_gazeOrigin,
                _gazeDirection,
                out hitInfo,
                GazeMaxDistance, LayerMask);
    
            HitInfo = hitInfo;
    
            // Check whether raycast has hit.
            if (Hit == true)
            {
                Position = hitInfo.point;
    
                Normal = hitInfo.normal;
    
                // Check whether the hit has a collider.
                if (hitInfo.collider != null)
                {
                    // Set the focused object with what the user just looked at.
                    FocusedObject = hitInfo.collider.gameObject;
                }
                else
                {
                    // Object looked on is not valid, set focused gameobject to null.
                    FocusedObject = null;
                }
            }
            else
            {
                // No object looked upon, set focused gameobject to null.
                FocusedObject = null;
    
                // Provide default position for cursor.
                Position = _gazeOrigin + (_gazeDirection * GazeMaxDistance);
    
                // Provide a default normal.
                Normal = _gazeDirection;
            }
    
            // Lerp the cursor to the given position, which helps to stabilize the gaze.
            Cursor.transform.position = Vector3.Lerp(Cursor.transform.position, Position, 0.6f);
    
            // Check whether the previous focused object is this same 
            //    object. If so, reset the focused object.
            if (FocusedObject != _oldFocusedObject)
            {
                ResetFocusedObject();
    
                if (FocusedObject != null)
                {
                if (FocusedObject.CompareTag(InteractibleTag.ToString()))
                {
                        // Set the Focused object to green - success!
                        FocusedObject.GetComponent<Renderer>().material.color = Color.green;
    
                        // Start the Azure Function, to provide the next shape!
                        AzureServices.instance.CallAzureFunctionForNextShape();
                    }
                }
            }
        }
    
  4. Infine, aggiungere il metodo ResetFocusedObject () , che consente di impostare il colore corrente per gli oggetti GazeButton, che indica se sta creando una nuova forma.Lastly, add the ResetFocusedObject() method, which will toggle the GazeButton objects current color, indicating whether it is creating a new shape or not.

        /// <summary>
        /// Reset the old focused object, stop the gaze timer, and send data if it
        /// is greater than one.
        /// </summary>
        private void ResetFocusedObject()
        {
            // Ensure the old focused object is not null.
            if (_oldFocusedObject != null)
            {
                if (_oldFocusedObject.CompareTag(InteractibleTag.ToString()))
                {
                    // Set the old focused object to red - its original state.
                    _oldFocusedObject.GetComponent<Renderer>().material.color = Color.red;
                }
            }
        }
    
  5. Salvare le modifiche in Visual Studio prima di tornare a Unity.Save your changes in Visual Studio before returning to Unity.

  6. Fare clic e trascinare la classe sguardi dalla cartella Scripts all'oggetto principale della fotocamera nel Pannello gerarchia.Click and drag the Gaze class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

Capitolo 10-completamento della classe serviziChapter 10 - Completing the AzureServices class

Con gli altri script sul posto, è ora possibile completare la classe Servizi .With the other scripts in place, it is now possible to complete the AzureServices class. Questa operazione verrà eseguita tramite:This will be achieved through:

  1. Aggiunta di un nuovo metodo denominato CreateCloudIdentityAsync () per configurare le variabili di autenticazione necessarie per la comunicazione con Azure.Adding a new method named CreateCloudIdentityAsync(), to set up the authentication variables needed for communicating with Azure.

    Questo metodo verificherà anche l'esistenza di un file archiviato in precedenza contenente l'elenco di forme.This method will also check for the existence of a previously stored File containing the Shape List.

    Se il file viene trovato, lo sguardo dell'utente viene disabilitato e viene attivata la creazione della forma, in base al modello di forme, come archiviato nel file di archiviazione di Azure.If the file is found, it will disable the user Gaze, and trigger Shape creation, according to the pattern of shapes, as stored in the Azure Storage file. L'utente può visualizzarlo, perché la mesh di testo fornirà la visualizzazione ' storage ' o ' New ', a seconda delle forme Origin.The user can see this, as the Text Mesh will provide display 'Storage' or 'New', depending on the shapes origin.

    Se non viene trovato alcun file, verrà abilitato lo sguardo, consentendo all'utente di creare forme quando si esamina l'oggetto GazeButton nella scena.If no file is found, it will enable the Gaze, enabling the user to create shapes when looking at the GazeButton object in the scene.

        /// <summary>
        /// Create the references necessary to log into Azure
        /// </summary>
        private async void CreateCloudIdentityAsync()
        {
            // Retrieve storage account information from connection string
            storageAccount = CloudStorageAccount.Parse(storageConnectionString);
    
            // Create a file client for interacting with the file service.
            fileClient = storageAccount.CreateCloudFileClient();
    
            // Create a share for organizing files and directories within the storage account.
            share = fileClient.GetShareReference(fileShare);
    
            await share.CreateIfNotExistsAsync();
    
            // Get a reference to the root directory of the share.
            CloudFileDirectory root = share.GetRootDirectoryReference();
    
            // Create a directory under the root directory
            dir = root.GetDirectoryReference(storageDirectory);
    
            await dir.CreateIfNotExistsAsync();
    
            //Check if the there is a stored text file containing the list
            shapeIndexCloudFile = dir.GetFileReference("TextShapeFile");
    
            if (!await shapeIndexCloudFile.ExistsAsync())
            {
                // File not found, enable gaze for shapes creation
                Gaze.instance.GazeEnabled = true;
    
                azureStatusText.text = "No Shape\nFile!";
            }
            else
            {
                // The file has been found, disable gaze and get the list from the file
                Gaze.instance.GazeEnabled = false;
    
                azureStatusText.text = "Shape File\nFound!";
    
                await ReplicateListFromAzureAsync();
            }
        }
    
  2. Il frammento di codice successivo si trova all'interno del metodo Start () ; dove verrà effettuata una chiamata al metodo CreateCloudIdentityAsync () .The next code snippet is from within the Start() method; wherein a call will be made to the CreateCloudIdentityAsync() method. È possibile copiare il metodo Start () corrente con il seguente:Feel free to copy over your current Start() method, with the below:

        private void Start()
        {
            // Disable TLS cert checks only while in Unity Editor (until Unity adds support for TLS)
    #if UNITY_EDITOR
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    #endif
    
            // Set the Status text to loading, whilst attempting connection to Azure.
            azureStatusText.text = "Loading...";
    
            //Creating the references necessary to log into Azure and check if the Storage Directory is empty
            CreateCloudIdentityAsync();
        }
    
  3. Compilare il codice per il metodo CallAzureFunctionForNextShape ().Fill in the code for the method CallAzureFunctionForNextShape(). Si userà la app per le funzioni di Azure creata in precedenza per richiedere un indice delle forme.You will use the previously created Azure Function App to request a shape index. Una volta ricevuta la nuova forma, questo metodo invierà la forma alla classe ShapeFactory per creare la nuova forma nella scena.Once the new shape is received, this method will send the shape to the ShapeFactory class to create the new shape in the scene. Usare il codice seguente per completare il corpo di CallAzureFunctionForNextShape ().Use the code below to complete the body of CallAzureFunctionForNextShape().

        /// <summary>
        /// Call to the Azure Function App to request a Shape.
        /// </summary>
        public async void CallAzureFunctionForNextShape()
        {
            int azureRandomInt = 0;
    
            // Call Azure function
            HttpWebRequest webRequest = WebRequest.CreateHttp(azureFunctionEndpoint);
    
            WebResponse response = await webRequest.GetResponseAsync();
    
            // Read response as string
            using (Stream stream = response.GetResponseStream())
            {
                StreamReader reader = new StreamReader(stream);
    
                String responseString = reader.ReadToEnd();
    
                //parse result as integer
                Int32.TryParse(responseString, out azureRandomInt);
            }
    
            //add random int from Azure to the ShapeIndexList
            ShapeFactory.instance.shapeHistoryList.Add(azureRandomInt);
    
            ShapeFactory.instance.CreateShape(azureRandomInt, false);
    
            //Save to Azure storage
            await UploadListToAzureAsync();
        }
    
  4. Aggiungere un metodo per creare una stringa concatenando gli Integer archiviati nell'elenco della cronologia delle forme e salvarli nel file di archiviazione di Azure.Add a method to create a string, by concatenating the integers stored in the shape history list, and saving it in your Azure Storage File.

        /// <summary>
        /// Upload the locally stored List to Azure
        /// </summary>
        private async Task UploadListToAzureAsync()
        {
            // Uploading a local file to the directory created above
            string listToString = string.Join(",", ShapeFactory.instance.shapeHistoryList.ToArray());
    
            await shapeIndexCloudFile.UploadTextAsync(listToString);
        }
    
  5. Aggiungere un metodo per recuperare il testo archiviato nel file che si trova nel file di archiviazione di Azure e deserializzarlo in un elenco.Add a method to retrieve the text stored in the file located in your Azure Storage File and deserialize it into a list.

  6. Una volta completato il processo, il metodo abilita nuovamente lo sguardo in modo che l'utente possa aggiungere altre forme alla scena.Once this process is completed, the method re-enables the gaze so that the user can add more shapes to the scene.

        ///<summary>
        /// Get the List stored in Azure and use the data retrieved to replicate 
        /// a Shape creation pattern
        ///</summary>
        private async Task ReplicateListFromAzureAsync()
        {
            string azureTextFileContent = await shapeIndexCloudFile.DownloadTextAsync();
    
            string[] shapes = azureTextFileContent.Split(new char[] { ',' });
    
            foreach (string shape in shapes)
            {
                int i;
    
                Int32.TryParse(shape.ToString(), out i);
    
                ShapeFactory.instance.shapeHistoryList.Add(i);
    
                ShapeFactory.instance.CreateShape(i, true);
    
                await Task.Delay(500);
            }
    
            Gaze.instance.GazeEnabled = true;
    
            azureStatusText.text = "Load Complete!";
        }
    
  7. Salvare le modifiche in Visual Studio prima di tornare a Unity.Save your changes in Visual Studio before returning to Unity.

Capitolo 11: compilare la soluzione UWPChapter 11 - Build the UWP Solution

Per avviare il processo di compilazione:To begin the Build process:

  1. Passare a file > impostazioni di compilazione.Go to File > Build Settings.

    compilare l'app

  2. Fare clic su Compila.Click Build. Unity avvierà una finestra di Esplora file , in cui è necessario creare e quindi selezionare una cartella in cui compilare l'app.Unity will launch a File Explorer window, where you need to create and then select a folder to build the app into. Creare la cartella adesso e denominarla app.Create that folder now, and name it App. Quindi, con la cartella dell' app selezionata, fare clic su Seleziona cartella.Then with the App folder selected, press Select Folder.

  3. Unity inizierà a compilare il progetto nella cartella dell' app .Unity will begin building your project to the App folder.

  4. Una volta completata la compilazione di Unity (potrebbe richiedere del tempo), verrà aperta una finestra Esplora file nella posizione della compilazione (controllare la barra delle applicazioni, perché potrebbe non essere sempre visualizzata sopra le finestre, ma verrà inviata una notifica sull'aggiunta di una nuova finestra).Once Unity has finished building (it might take some time), it will open a File Explorer window at the location of your build (check your task bar, as it may not always appear above your windows, but will notify you of the addition of a new window).

Capitolo 12-distribuzione dell'applicazioneChapter 12 - Deploying your application

Per distribuire l'applicazione:To deploy your application:

  1. Passare alla cartella dell' app creata nell' ultimo capitolo.Navigate to the App folder which was created in the last Chapter. Verrà visualizzato un file con il nome delle app, con l'estensione ' sln ', che è necessario fare doppio clic, per aprirlo in Visual Studio.You will see a file with your apps name, with the '.sln' extension, which you should double-click, so to open it within Visual Studio.

  2. Nella piattaforma soluzione selezionare x86, computer locale.In the Solution Platform, select x86, Local Machine.

  3. Nella configurazione della soluzione selezionare debug.In the Solution Configuration select Debug.

    Per Microsoft HoloLens, può risultare più semplice impostare questa impostazione su computer remoto, in modo da non essere collegati al computer.For the Microsoft HoloLens, you may find it easier to set this to Remote Machine, so that you are not tethered to your computer. Tuttavia, sarà necessario eseguire anche le operazioni seguenti:Though, you will need to also do the following:

    • Individuare l' indirizzo IP della HoloLens, che si trova all'interno della rete Impostazioni > & > Opzioni avanzate Wi-Fi > . l'indirizzo IPv4 è quello da usare.Know the IP Address of your HoloLens, which can be found within the Settings > Network & Internet > Wi-Fi > Advanced Options; the IPv4 is the address you should use.
    • Verificare che la modalità sviluppatore sia attiva; disponibile in Impostazioni > aggiornare & sicurezza > per gli sviluppatori.Ensure Developer Mode is On; found in Settings > Update & Security > For developers.

    Distribuisci soluzione

  4. Passare al menu Compila e fare clic su Distribuisci soluzione per sideload l'applicazione al computer.Go to the Build menu and click on Deploy Solution to sideload the application to your machine.

  5. L'app verrà visualizzata nell'elenco delle app installate, pronta per essere avviata e testata.Your App should now appear in the list of installed apps, ready to be launched and tested!

Le funzioni di Azure e l'applicazione di archiviazione completateYour finished Azure Functions and Storage Application

Congratulazioni, è stata creata un'app per realtà mista che sfrutta sia le funzioni di Azure che i servizi di archiviazione di Azure.Congratulations, you built a mixed reality app that leverages both the Azure Functions and Azure Storage services. L'app sarà in grado di creare dati archiviati e fornirà un'azione in base a tali dati.Your app will be able to draw on stored data, and provide an action based on that data.

fine prodotto finale

Esercizi aggiuntiviBonus exercises

Esercizio 1Exercise 1

Creare un secondo punto di spawn e registrare il punto di generazione da cui è stato creato un oggetto.Create a second spawn point and record which spawn point an object was created from. Quando si carica il file di dati, riprodurre le forme generate dalla posizione in cui sono state create originariamente.When you load the data file, replay the shapes being spawned from the location they originally were created.

Esercizio 2Exercise 2

Creare un modo per riavviare l'app, anziché riaprirla ogni volta.Create a way to restart the app, rather than having to re-open it each time. Il caricamento di scene è un punto di partenza valido.Loading Scenes is a good spot to start. Al termine di questa operazione, creare un modo per cancellare l'elenco Archiviato in archiviazione di Azure, in modo che possa essere facilmente reimpostato dall'app.After doing that, create a way to clear the stored list in Azure Storage, so that it can be easily reset from your app.