Share via


HoloLens (1ère génération) et Azure 305 : Fonctions et stockage


Notes

Les tutoriels Mixed Reality Academy ont été conçus pour les appareils HoloLens (1re génération) et les casques immersifs de réalité mixte. Nous estimons qu’il est important de laisser ces tutoriels à la disposition des développeurs qui recherchent encore des conseils pour développer des applications sur ces appareils. Notez que ces tutoriels ne sont pas mis à jour avec les derniers ensembles d’outils ou interactions utilisés pour HoloLens 2. Ils sont fournis dans le but de fonctionner sur les appareils pris en charge. Il y aura une nouvelle série de tutoriels qui seront publiés à l’avenir et qui montreront comment développer pour HoloLens 2. Cet avis sera mis à jour avec un lien vers ces tutoriels lorsqu’ils seront publiés.


produit final -start

Dans ce cours, vous allez apprendre à créer et à utiliser des Azure Functions et à stocker des données avec une ressource Stockage Azure, dans une application de réalité mixte.

Azure Functions est un service Microsoft, qui permet aux développeurs d’exécuter de petits morceaux de code, des « fonctions », dans Azure. Cela permet de déléguer le travail au cloud, plutôt qu’à votre application locale, ce qui peut présenter de nombreux avantages. Azure Functions prend en charge plusieurs langages de développement, notamment C#, F#, Node.js, Java et PHP. Pour plus d’informations, consultez l’article Azure Functions.

Stockage Azure est un service cloud Microsoft, qui permet aux développeurs de stocker des données, avec l’assurance qu’elles seront hautement disponibles, sécurisées, durables, évolutives et redondantes. Cela signifie que Microsoft gère toutes les maintenances et les problèmes critiques pour vous. Pour plus d’informations, consultez l’article Stockage Azure.

Après avoir terminé ce cours, vous disposerez d’une application de casque immersif de réalité mixte qui sera en mesure d’effectuer les opérations suivantes :

  1. Autoriser l’utilisateur à regarder autour d’une scène.
  2. Déclenchez la génération d’objets lorsque l’utilisateur regarde un « bouton » 3D.
  3. Les objets générés seront choisis par une fonction Azure.
  4. À mesure que chaque objet est généré, l’application stocke le type d’objet dans un fichier Azure, situé dans stockage Azure.
  5. Lors du chargement d’une deuxième fois, les données Azure File sont récupérées et utilisées pour relire les actions de génération de la instance précédente de l’application.

Dans votre application, il vous appartient de savoir comment intégrer les résultats à votre conception. Ce cours est conçu pour vous apprendre à intégrer un service Azure à votre projet Unity. Il vous incombe d’utiliser les connaissances que vous obtenez de ce cours pour améliorer votre application de réalité mixte.

Prise en charge des appareils

Cours HoloLens Casques immersifs
Réalité mixte - Azure - Cours 305 : Fonctions et stockage ✔️ ✔️

Notes

Bien que ce cours se concentre principalement sur Windows Mixed Reality casques immersifs (VR), vous pouvez également appliquer ce que vous avez appris dans ce cours à Microsoft HoloLens. À mesure que vous suivez le cours, vous verrez des notes sur les modifications que vous devrez peut-être utiliser pour prendre en charge HoloLens.

Prérequis

Notes

Ce tutoriel est conçu pour les développeurs qui ont une expérience de base avec Unity et C#. Sachez également que les conditions préalables et les instructions écrites contenues dans ce document représentent ce qui a été testé et vérifié au moment de la rédaction (mai 2018). Vous êtes libre d’utiliser les logiciels les plus récents, comme indiqué dans l’article Installer les outils , mais il ne faut pas supposer que les informations de ce cours correspondent parfaitement à ce que vous trouverez dans les logiciels plus récents que ce qui est listé ci-dessous.

Nous vous recommandons d’utiliser le matériel et les logiciels suivants pour ce cours :

Avant de commencer

Pour éviter de rencontrer des problèmes lors de la création de ce projet, il est fortement recommandé de créer le projet mentionné dans ce didacticiel dans un dossier racine ou proche de la racine (les chemins de dossier longs peuvent entraîner des problèmes au moment de la génération).

Chapitre 1 : Le portail Azure

Pour utiliser le service Stockage Azure, vous devez créer et configurer un compte de stockage dans le Portail Azure.

  1. Connectez-vous au portail Azure.

    Notes

    Si vous n’avez pas encore de compte Azure, vous devez en créer un. Si vous suivez ce tutoriel dans une situation de classe ou de laboratoire, demandez à votre instructeur ou à l’un des surveillants de l’aide pour configurer votre nouveau compte.

  2. Une fois que vous êtes connecté, cliquez sur Nouveau dans le coin supérieur gauche, recherchez Compte de stockage, puis cliquez sur Entrée.

    Recherche de stockage azure

    Notes

    Le mot Nouveau a peut-être été remplacé par Créer une ressource, dans les portails plus récents.

  3. La nouvelle page fournit une description du service de compte de stockage Azure . En bas à gauche de cette invite, sélectionnez le bouton Créer pour créer une association avec ce service.

    créer un service

  4. Une fois que vous avez cliqué sur Créer :

    1. Insérez un nom pour votre compte. N’oubliez pas que ce champ accepte uniquement les chiffres et les lettres minuscules.

    2. Pour Modèle de déploiement, sélectionnez Gestionnaire de ressources.

    3. Pour Type de compte, sélectionnez Stockage (usage général v1).

    4. Déterminez l’emplacement de votre groupe de ressources (si vous créez un groupe de ressources). L’emplacement serait idéalement dans la région où l’application s’exécuterait. Certaines ressources Azure ne sont disponibles que dans certaines régions.

    5. Pour Réplication, sélectionnez Stockage géoredondant avec accès en lecture (RA-GRS).

    6. Pour Performances, sélectionnez Standard.

    7. Laissez Transfert sécurisé requissur Désactivé.

    8. Sélectionnez un Abonnement.

    9. Choisissez un groupe de ressources ou créez-en un. Un groupe de ressources permet de surveiller, de contrôler l’accès, de provisionner et de gérer la facturation d’une collection de ressources Azure. Il est recommandé de conserver tous les services Azure associés à un seul projet (par exemple, ces labos) sous un groupe de ressources commun).

      Si vous souhaitez en savoir plus sur les groupes de ressources Azure, consultez l’article sur les groupes de ressources.

    10. Vous devez également confirmer que vous avez bien compris les conditions générales appliquées à ce service.

    11. Sélectionnez Create (Créer).

      informations sur le service d’entrée

  5. Une fois que vous avez cliqué sur Créer, vous devrez attendre que le service soit créé, ce qui peut prendre une minute.

  6. Une notification s’affiche dans le portail une fois le service instance créé.

    nouvelle notification dans le portail Azure

  7. Cliquez sur les notifications pour explorer votre nouveau service instance.

    accéder à la ressource

  8. Cliquez sur le bouton Accéder à la ressource dans la notification pour explorer votre nouvelle instance de service. Vous serez redirigé vers votre nouvelle instance de service de compte de stockage.

    clés d’accès

  9. Cliquez sur Clés d’accès pour afficher les points de terminaison de ce service cloud. Utilisez le Bloc-notes ou similaire pour copier l’une de vos touches pour une utilisation ultérieure. Notez également la valeur chaîne de connexion , car elle sera utilisée dans la classe AzureServices , que vous créerez ultérieurement.

    copier chaîne de connexion

Chapitre 2 - Configuration d’une fonction Azure

Vous allez maintenant écrire une fonctionAzure dans le service Azure.

Vous pouvez utiliser une fonction Azure pour effectuer presque tout ce que vous feriez avec une fonction classique dans votre code, à la différence près que cette fonction est accessible à n’importe quelle application disposant d’informations d’identification pour accéder à votre compte Azure.

Pour créer une fonction Azure :

  1. Dans votre portail Azure, cliquez sur Nouveau dans le coin supérieur gauche, recherchez Application de fonction, puis cliquez sur Entrée.

    créer une application de fonction

    Notes

    Le mot Nouveau a peut-être été remplacé par Créer une ressource, dans les portails plus récents.

  2. La nouvelle page fournit une description du service Azure Function App . En bas à gauche de cette invite, sélectionnez le bouton Créer pour créer une association avec ce service.

    informations sur l’application de fonction

  3. Une fois que vous avez cliqué sur Créer :

    1. Indiquez un nom d’application. Seuls les lettres et les chiffres peuvent être utilisés ici (majuscules ou minuscules autorisés).

    2. Sélectionnez votre abonnement préféré.

    3. Choisissez un groupe de ressources ou créez-en un. Un groupe de ressources permet de surveiller, de contrôler l’accès, de provisionner et de gérer la facturation pour une collection de ressources Azure. Il est recommandé de conserver tous les services Azure associés à un seul projet (par exemple, ces labos) sous un groupe de ressources commun.

      Si vous souhaitez en savoir plus sur les groupes de ressources Azure, consultez l’article sur les groupes de ressources.

    4. Pour cet exercice, sélectionnez Windows comme système d’exploitation choisi.

    5. Sélectionnez Plan de consommation pour le plan d’hébergement.

    6. Déterminez l’emplacement de votre groupe de ressources (si vous créez un groupe de ressources). L’emplacement est idéalement situé dans la région où l’application s’exécuterait. Certaines ressources Azure sont disponibles uniquement dans certaines régions. Pour des performances optimales, sélectionnez la même région que le compte de stockage.

    7. Pour Stockage, sélectionnez Utiliser existant, puis, à l’aide du menu déroulant, recherchez le stockage créé précédemment.

    8. Laissez Application Insights désactivé pour cet exercice.

      détails de l’application de fonction d’entrée

  4. Cliquez sur le bouton Créer.

  5. Une fois que vous avez cliqué sur Créer, vous devrez attendre que le service soit créé, ce qui peut prendre une minute.

  6. Une notification s’affiche dans le portail une fois le service instance créé.

    nouvelle notification du portail Azure

  7. Cliquez sur les notifications pour explorer votre nouveau service instance.

    Accéder à l’application de fonction de ressource

  8. Cliquez sur le bouton Accéder à la ressource dans la notification pour explorer votre nouvelle instance de service. Vous serez redirigé vers votre nouvelle instance Function App Service.

  9. Dans le tableau de bord Application de fonction, placez votre souris sur Functions, qui se trouve dans le panneau de gauche, puis cliquez sur le symbole + (plus).

    créer une fonction

  10. Dans la page suivante, vérifiez que Webhook + API est sélectionné, puis, pour Choisir une langue, sélectionnez CSharp, car il s’agit de la langue utilisée pour ce didacticiel. Enfin, cliquez sur le bouton Créer cette fonction .

    sélectionner web hook csharp

  11. Vous devez être dirigé vers la page de code (run.csx). Si ce n’est pas le cas, cliquez sur la fonction nouvellement créée dans la liste Fonctions dans le panneau de gauche.

    ouvrir une nouvelle fonction

  12. Copiez le code suivant dans votre fonction. Cette fonction retourne simplement un entier aléatoire compris entre 0 et 2 lorsqu’elle est appelée. Ne vous inquiétez pas du code existant, n’hésitez pas à le coller par-dessus.

        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. Sélectionnez Enregistrer.

  14. Le résultat doit ressembler à l’image ci-dessous.

  15. Cliquez sur Obtenir l’URL de la fonction et notez le point de terminaison affiché. Vous devrez l’insérer dans la classe AzureServices que vous créerez plus loin dans ce cours.

    Obtenir le point de terminaison de fonction

    Insérer un point de terminaison de fonction

Chapitre 3 - Configuration du projet Unity

Ce qui suit est une configuration classique pour le développement avec Mixed Reality et, en tant que tel, est un bon modèle pour d’autres projets.

Configurez et testez votre casque immersif de réalité mixte.

Notes

Vous n’aurez pas besoin de contrôleurs de mouvement pour ce cours. Si vous avez besoin d’aide pour configurer le casque immersif, consultez l’article sur la configuration de la réalité mixte.

  1. Ouvrez Unity, puis cliquez sur Nouveau.

    Créer un projet unity

  2. Vous devez maintenant fournir un nom de projet Unity. Insérez MR_Azure_Functions. Vérifiez que le type de projet est défini sur 3D. Définissez l’emplacement sur un emplacement approprié (n’oubliez pas qu’il est préférable de se rapprocher des répertoires racines). Cliquez ensuite sur Créer un projet.

    Donnez un nom au nouveau projet unity

  3. Avec Unity ouvert, il est utile de vérifier que l’Éditeur de script par défaut est défini sur Visual Studio. Accédez à Modifier les>préférences , puis, dans la nouvelle fenêtre, accédez à Outils externes. Remplacez Éditeur de script externe par Visual Studio 2017. Fermez la fenêtre Préférences.

    définir Visual Studio en tant qu’éditeur de script

  4. Ensuite, accédez à>Paramètres de génération de fichiers et basculez la plateforme sur plateforme Windows universelle, en cliquant sur le bouton Changer de plateforme.

    basculer la plateforme vers uwp

  5. Accédez à Paramètres>de génération de fichiers et assurez-vous que :

    1. L’appareil cible est défini sur N’importe quel appareil.

      Pour Microsoft HoloLens, définissez l’appareil cible sur HoloLens.

    2. Type de build défini sur D3D

    3. Le Kit de développement logiciel (SDK) est défini sur Dernier installé

    4. La version de Visual Studio est définie sur Dernière installation

    5. Générer et exécuter est défini sur Ordinateur local

    6. Enregistrez la scène et ajoutez-la à la build.

      1. Pour ce faire, sélectionnez Ajouter des scènes ouvertes. Une fenêtre d’enregistrement s’affiche.

        ajouter des scènes ouvertes

      2. Créez un dossier pour cette scène et toute autre scène future, puis sélectionnez le bouton Nouveau dossier pour créer un dossier, nommez-le Scènes.

        créer un dossier de scènes

      3. Ouvrez votre dossier Scènes nouvellement créé, puis dans le champ Nom de fichier : texte, tapez FunctionsScene, puis appuyez sur Enregistrer.

        Enregistrer la scène des fonctions

  6. Les autres paramètres, dans Paramètres de build, doivent être conservés par défaut pour l’instant.

    Conserver les paramètres de build par défaut

  7. Dans la fenêtre Paramètres de build, cliquez sur le bouton Paramètres du lecteur. Le panneau associé s’ouvre dans l’espace où se trouve l’inspecteur.

    paramètres du lecteur dans l’inspecteur

  8. Dans ce panneau, quelques paramètres doivent être vérifiés :

    1. Sous l’onglet Autres paramètres :

      1. La version du runtime de script doit être expérimentale (équivalent.NET 4.6), ce qui déclenche la nécessité de redémarrer l’éditeur.
      2. Le serveur principal de script doit être .NET
      3. Le niveau de compatibilité de l’API doit être .NET 4.6
    2. Sous l’onglet Paramètres de publication, sous Fonctionnalités, case activée :

      • InternetClient

        définir des fonctionnalités

    3. Plus loin dans le panneau, dans Paramètres XR (ci-dessous Paramètres de publication), cochez Réalité virtuelle prise en charge, vérifiez que l’Windows Mixed Reality SDK est ajouté.

      définir les paramètres XR

  9. Retour dans Paramètres de buildUnity C# Projects n’est plus grisé ; cochez la case à côté de cette case.

    Cochez les projets c#

  10. Fermez la fenêtre Build Settings.

  11. Enregistrez votre scène et votre projet (FILE>SAVE SCENE / FILE>SAVE PROJECT).

Chapitre 4 - Configurer la caméra principale

Important

Si vous souhaitez ignorer les composants De configuration Unity de ce cours et continuer directement dans le code, n’hésitez pas à télécharger ce fichier .unitypackage et à l’importer dans votre projet en tant que package personnalisé. Cela contiendra également les DLL du chapitre suivant. Après l’importation, passez au chapitre 7.

  1. Dans le panneau hiérarchie, vous trouverez un objet appelé Main Camera, cet objet représente votre point de vue « tête » une fois que vous êtes « à l’intérieur » de votre application.

  2. Avec le tableau de bord Unity devant vous, sélectionnez l’objet GameObject de la caméra principale. Vous remarquerez que le panneau d’inspecteur (généralement situé à droite, dans le tableau de bord) affiche les différents composants de ce GameObject, avec Transform en haut, suivi de Caméra et d’autres composants. Vous devez réinitialiser la transformation de la caméra principale afin qu’elle soit correctement positionnée.

  3. Pour ce faire, sélectionnez l’icône Engrenage en regard du composant Transformer de l’appareil photo, puis sélectionnez Réinitialiser.

    réinitialiser la transformation

  4. Ensuite, mettez à jour le composant Transform pour qu’il ressemble à :

Transformer - Position

X O Z
0 1 0

Transformer - Rotation

X O Z
0 0 0

Transformer - Mettre à l’échelle

X O Z
1 1 1

définir la transformation de la caméra

Chapitre 5 - Configuration de la scène Unity

  1. Cliquez avec le bouton droit dans une zone vide du panneau hiérarchie, sous Objet 3D, ajoutez un plan.

    créer un plan

  2. Une fois l’objet Plane sélectionné, modifiez les paramètres suivants dans le panneau d’inspecteur :

Transformer - Position

X O Z
0 0 4

Transformer - Mettre à l’échelle

X O Z
10 1 10

définir la position et l’échelle du plan

vue de scène du plan

  1. Cliquez avec le bouton droit dans une zone vide du panneau hiérarchie, sous Objet 3D, ajoutez un cube.

    1. Renommez le cube en GazeButton (avec le cube sélectionné, appuyez sur « F2 »).

    2. Modifiez les paramètres suivants pour Transformer la position dans le panneau d’inspecteur :

      X O Z
      0 3 5

      définir la transformation du bouton de regard

      Vue de la scène du bouton de regard

    3. Cliquez sur le bouton déroulant Balise , puis cliquez sur Ajouter une balise pour ouvrir le volet Balises & calques.

      ajouter une nouvelle balise

      sélectionner plus

    4. Sélectionnez le bouton + (plus), puis dans le champ Nouveau nom de balise , entrez GazeButton, puis appuyez sur Enregistrer.

      name new tag

    5. Cliquez sur l’objet GazeButton dans le panneau hierarchy et, dans le panneau d’inspecteur, affectez la balise GazeButton nouvellement créée.

      affecter le bouton de regard à la nouvelle balise

  2. Cliquez avec le bouton droit sur l’objet GazeButton , dans le panneau Hierarchy, puis ajoutez un GameObject vide (qui sera ajouté en tant qu’objet enfant ).

  3. Sélectionnez le nouvel objet et renommez-le ShapeSpawnPoint.

    1. Modifiez les paramètres suivants pour Transformer la position dans le panneau d’inspecteur :

      X O Z
      0 -1 0

      mettre à jour la transformation du point de génération de forme

      vue scène du point de génération de forme

  4. Vous allez ensuite créer un objet Texte 3D pour fournir des commentaires sur le status du service Azure.

    Cliquez à nouveau avec le bouton droit sur le GazeButton dans le panneau de hiérarchie et ajoutez un objet Texte 3D Object>3D en tant qu’enfant.

    créer un objet texte 3D

  5. Renommez l’objet 3D Text en AzureStatusText.

  6. Modifiez l’objet AzureStatusTextTransform Position comme suit :

    X O Z
    0 0 -0.6
  7. Modifiez l’objet AzureStatusTextTransform Scale comme suit : | X | Y | Z | | | :---: | :---: | :---: | | 0,1 | 0,1 | 0,1 |

    Notes

    Ne vous inquiétez pas s’il semble être hors centre, car cela sera résolu lorsque le composant Maillage de texte ci-dessous sera mis à jour.

  8. Modifiez le composant Maillage de texte pour qu’il corresponde à ce qui suit :

    définir le composant de maillage de texte

    Conseil

    La couleur sélectionnée ici est Hex color : 000000FF, bien que n’hésitez pas à choisir votre propre, assurez-vous qu’elle est lisible.

  9. La structure du panneau hiérarchique doit maintenant ressembler à ceci :

    Maillage de texte dans la hiérarchie

  10. Votre scène doit maintenant ressembler à ceci :

    Maillage de texte en mode scène

Chapitre 6 - Importer stockage Azure pour Unity

Vous allez utiliser Stockage Azure pour Unity (qui tire lui-même parti du Kit de développement logiciel (SDK) .Net pour Azure. Pour plus d’informations à ce sujet, consultez l’article Stockage Azure pour Unity.

Il existe actuellement un problème connu dans Unity qui nécessite la reconfiguration des plug-ins après l’importation. Ces étapes (4 à 7 dans cette section) ne seront plus nécessaires une fois le bogue résolu.

Pour importer le KIT de développement logiciel (SDK) dans votre propre projet, vérifiez que vous avez téléchargé la dernière version « .unitypackage » à partir de GitHub. Ensuite, procédez comme suit :

  1. Ajoutez le fichier .unitypackage à Unity à l’aide de l’option de menu Importer> lepackage>personnalisé de ressources.

  2. Dans la zone Importer le package Unity qui s’affiche, vous pouvez sélectionner tout sousStockage deplug-in>. Décochez tout le reste, car il n’est pas nécessaire pour ce cours.

    importer dans le package

  3. Cliquez sur le bouton Importer pour ajouter les éléments à votre projet.

  4. Accédez au dossier Stockage sous Plug-ins, dans la vue Projet, puis sélectionnez les plug-ins suivants uniquement :

    • Microsoft.Data.Edm

    • Microsoft.Data.OData

    • Microsoft.WindowsAzure.Storage

    • Newtonsoft.Json

    • System.Spatial

      décochez n’importe quelle plateforme.

  5. Une fois ces plug-ins spécifiques sélectionnés, décochezToutes les plateformes , décochezWSAPlayer , puis cliquez sur Appliquer.

    appliquer des dll de plateforme

    Notes

    Nous marquageons ces plug-ins particuliers à utiliser uniquement dans l’éditeur Unity. Cela est dû au fait qu’il existe différentes versions des mêmes plug-ins dans le dossier WSA qui seront utilisées après l’exportation du projet à partir d’Unity.

  6. Dans le dossier du plug-in stockage , sélectionnez uniquement :

    • Microsoft.Data.Services.Client

      set don’t process for dlls

  7. Cochez la case Ne pas traiter sous Paramètres de la plateforme , puis cliquez sur Appliquer.

    n’appliquer aucun traitement

    Notes

    Nous marqueons ce plug-in « Ne pas traiter », car le correctif d’assembly Unity a des difficultés à traiter ce plug-in. Le plug-in fonctionnera toujours même s’il n’est pas traité.

Chapitre 7 - Créer la classe AzureServices

La première classe que vous allez créer est la classe AzureServices .

La classe AzureServices sera responsable des opérations suivantes :

  • Stockage des informations d’identification du compte Azure.

  • Appel de votre fonction Azure App.

  • Chargement et téléchargement du fichier de données dans votre stockage cloud Azure.

Pour créer cette classe :

  1. Cliquez avec le bouton droit dans le dossier De ressources , situé dans le volet Projet, Créer un>dossier. Nommez le dossier Scripts.

    créer un dossier

    dossier d’appel - scripts

  2. Double-cliquez sur le dossier que vous venez de créer pour l’ouvrir.

  3. Cliquez avec le bouton droit dans le dossier Créer un>script C#. Appelez le script AzureServices.

  4. Double-cliquez sur la nouvelle classe AzureServices pour l’ouvrir avec Visual Studio.

  5. Ajoutez les espaces de noms suivants en haut d’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. Ajoutez les champs d’inspecteur suivants à l’intérieur de la classe AzureServices :

        /// <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. Ajoutez ensuite les variables membres suivantes à l’intérieur de la classe AzureServices :

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

    Important

    Veillez à remplacer le point de terminaison et les valeurs chaîne de connexion par les valeurs de votre stockage Azure, qui se trouvent dans le portail Azure.

  8. Le code pour les méthodes Awake() et Start() doit maintenant être ajouté. Ces méthodes seront appelées lorsque la classe initialise :

        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()
        {
    
        }
    

    Important

    Nous remplirons le code pour CallAzureFunctionForNextShape() dans un prochain chapitre.

  9. Supprimez la méthode Update(), car cette classe ne l’utilisera pas.

  10. Enregistrez vos modifications dans Visual Studio, puis revenez à Unity.

  11. Cliquez et faites glisser la classe AzureServices du dossier Scripts vers l’objet Main Camera dans le panneau Hiérarchie.

  12. Sélectionnez la caméra principale, puis récupérez l’objet enfant AzureStatusText sous l’objet GazeButton et placez-le dans le champ cible de référence AzureStatusText, dans l’inspecteur, pour fournir la référence au script AzureServices.

    affecter une cible de référence de texte azure status

Chapitre 8 - Créer la classe ShapeFactory

Le script suivant à créer est la classe ShapeFactory . Le rôle de cette classe consiste à créer une nouvelle forme, quand elle est demandée, et à conserver un historique des formes créées dans une liste d’historique des formes. Chaque fois qu’une forme est créée, la liste Historique des formes est mise à jour dans la classe AzureService , puis stockée dans votre stockage Azure. Lorsque l’application démarre, si un fichier stocké se trouve dans votre stockage Azure, la liste Historique des formes est récupérée et relue, l’objet Texte 3D indiquant si la forme générée provient du stockage ou est nouvelle.

Pour créer cette classe :

  1. Accédez au dossier Scripts que vous avez créé précédemment.

  2. Cliquez avec le bouton droit dans le dossier Créer un>script C#. Appelez le script ShapeFactory.

  3. Double-cliquez sur le nouveau script ShapeFactory pour l’ouvrir avec Visual Studio.

  4. Vérifiez que la classe ShapeFactory inclut les espaces de noms suivants :

        using System.Collections.Generic;
        using UnityEngine;
    
  5. Ajoutez les variables ci-dessous à la classe ShapeFactory , puis remplacez les fonctions Start() et Awake() par celles ci-dessous :

        /// <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. La méthode CreateShape() génère les formes primitives, en fonction du paramètre entier fourni. Le paramètre Boolean est utilisé pour spécifier si la forme actuellement créée provient du stockage ou d’une nouvelle. Placez le code suivant dans votre classe ShapeFactory , sous les méthodes précédentes :

        /// <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. Veillez à enregistrer vos modifications dans Visual Studio avant de revenir à Unity.

  8. De retour dans l’éditeur Unity, cliquez et faites glisser la classe ShapeFactory du dossier Scripts vers l’objet Main Camera dans le panneau Hierarchy.

  9. Une fois la caméra principale sélectionnée, vous remarquerez que le composant de script ShapeFactory ne contient pas la référence point de génération . Pour le résoudre, faites glisser l’objet ShapeSpawnPoint du panneau de hiérarchie vers la cible de référence point de génération .

    définir la cible de référence de la fabrique de formes

Chapitre 9 - Créer la classe Regarde

Le dernier script que vous devez créer est la classe Gaze .

Cette classe est chargée de créer un Raycast qui sera projeté vers l’avant à partir de la caméra principale, pour détecter l’objet que l’utilisateur regarde. Dans ce cas, le Raycast doit identifier si l’utilisateur regarde l’objet GazeButton dans la scène et déclencher un comportement.

Pour créer cette classe :

  1. Accédez au dossier Scripts que vous avez créé précédemment.

  2. Cliquez avec le bouton droit dans le volet Projet, Créer un>script C#. Appelez le script Gaze.

  3. Double-cliquez sur le nouveau script Gaze pour l’ouvrir avec Visual Studio.

  4. Vérifiez que l’espace de noms suivant est inclus en haut du script :

        using UnityEngine;
    
  5. Ajoutez ensuite les variables suivantes à l’intérieur de la classe Gaze :

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

Important

Certaines de ces variables peuvent être modifiées dans l’éditeur.

  1. Le code des méthodes Awake() et Start() doit maintenant être ajouté.

        /// <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. Ajoutez le code suivant, qui créera un objet cursor au début, ainsi que la méthode Update(), qui exécutera la méthode Raycast, ainsi que l’emplacement où le booléen GazeEnabled est activé :

        /// <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. Ajoutez ensuite la méthode UpdateRaycast(), qui projette un Raycast et détecte la cible atteinte.

        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. Enfin, ajoutez la méthode ResetFocusedObject(), qui bascule la couleur actuelle des objets GazeButton, indiquant s’il crée une nouvelle forme ou non.

        /// <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. Enregistrez vos modifications dans Visual Studio avant de revenir à Unity.

  6. Cliquez et faites glisser la classe Regarde du dossier Scripts vers l’objet Main Camera dans le panneau hiérarchie.

Chapitre 10 - Fin de la classe AzureServices

Une fois les autres scripts en place, il est désormais possible de terminer la classe AzureServices . Pour ce faire, procédez comme suit :

  1. Ajout d’une nouvelle méthode nommée CreateCloudIdentityAsync() pour configurer les variables d’authentification nécessaires à la communication avec Azure.

    Cette méthode case activée également l’existence d’un fichier précédemment stocké contenant la liste de formes.

    Si le fichier est trouvé, il désactive le regard de l’utilisateur et déclenche la création de formes, en fonction du modèle de formes, telle qu’elle est stockée dans le fichier stockage Azure. L’utilisateur peut le voir, car le maillage de texte fournit l’affichage « Stockage » ou « Nouveau », en fonction de l’origine des formes.

    Si aucun fichier n’est trouvé, il active le regard, ce qui permet à l’utilisateur de créer des formes lorsqu’il examine l’objet GazeButton dans la scène.

        /// <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. L’extrait de code suivant provient de la méthode Start() ; où un appel est effectué à la méthode CreateCloudIdentityAsync(). N’hésitez pas à copier votre méthode Start() actuelle, avec les éléments ci-dessous :

        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. Renseignez le code de la méthode CallAzureFunctionForNextShape(). Vous utiliserez l’application de fonction Azure créée précédemment pour demander un index de forme. Une fois la nouvelle forme reçue, cette méthode envoie la forme à la classe ShapeFactory pour créer la nouvelle forme dans la scène. Utilisez le code ci-dessous pour compléter le corps de 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. Ajoutez une méthode pour créer une chaîne en concaténant les entiers stockés dans la liste d’historique des formes et en l’enregistrant dans votre fichier de stockage Azure.

        /// <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. Ajoutez une méthode pour récupérer le texte stocké dans le fichier situé dans votre fichier de stockage Azure et le désérialiser dans une liste.

  6. Une fois ce processus terminé, la méthode réactive le regard afin que l’utilisateur puisse ajouter d’autres formes à la scène.

        ///<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. Enregistrez vos modifications dans Visual Studio avant de revenir à Unity.

Chapitre 11 - Générer la solution UWP

Pour commencer le processus de génération :

  1. Accédez àParamètres de génération de fichiers>.

    générer l’application

  2. Cliquez sur Générer. Unity lance une fenêtre Explorateur de fichiers, dans laquelle vous devez créer, puis sélectionner un dossier dans lequel générer l’application. Créez ce dossier maintenant et nommez-le Application. Ensuite, avec le dossier Application sélectionné, appuyez sur Sélectionner un dossier.

  3. Unity commence à générer votre projet dans le dossier Application .

  4. Une fois la génération terminée (cela peut prendre un certain temps), Unity ouvre une fenêtre Explorateur de fichiers à l’emplacement de votre build (case activée votre barre des tâches, car elle n’apparaît peut-être pas toujours au-dessus de vos fenêtres, mais vous informe de l’ajout d’une nouvelle fenêtre).

Chapitre 12 - Déploiement de votre application

Pour déployer votre application :

  1. Accédez au dossier App qui a été créé dans le dernier chapitre. Vous verrez un fichier avec le nom de vos applications, avec l’extension '.sln', que vous devez double-cliquer, afin de l’ouvrir dans Visual Studio.

  2. Dans Plateforme de solution, sélectionnez x86, Ordinateur local.

  3. Dans configuration de la solution , sélectionnez Déboguer.

    Pour le Microsoft HoloLens, il peut être plus facile de définir cette option sur Ordinateur distant, afin de ne pas être attaché à votre ordinateur. Toutefois, vous devez également effectuer les opérations suivantes :

    • Connaissez l’adresse IP de votre HoloLens, qui se trouve dans les paramètres>réseau &>Options avancées internetWi-Fi>. IPv4 est l’adresse que vous devez utiliser.
    • Vérifiez que le mode développeur est activé ; trouvé dans Paramètres>Mise à jour & sécurité>pour les développeurs.

    déployer la solution

  4. Accédez au menu Générer , puis cliquez sur Déployer la solution pour charger une version test de l’application sur votre ordinateur.

  5. Votre application doit maintenant apparaître dans la liste des applications installées, prêtes à être lancées et testées !

Votre application Azure Functions et de stockage terminée

Félicitations, vous avez créé une application de réalité mixte qui tire parti des services Azure Functions et stockage Azure. Votre application pourra dessiner sur des données stockées et fournir une action basée sur ces données.

produit final -end

Exercices bonus

Exercice 1

Créez un deuxième point de frayeur et enregistrez le point de génération à partir duquel un objet a été créé. Lorsque vous chargez le fichier de données, relisez les formes créées à partir de l’emplacement où elles ont été créées à l’origine.

Exercice 2

Créez un moyen de redémarrer l’application, plutôt que d’avoir à la rouvrir à chaque fois. Le chargement des scènes est un bon point de départ. Après cela, créez un moyen d’effacer la liste stockée dans stockage Azure, afin qu’elle puisse être facilement réinitialisée à partir de votre application.