HoloLens (1. generace) a Azure 305: Funkce a úložiště


Poznámka

Kurzy Mixed Reality Academy byly navrženy s HoloLens (1. generace) a Mixed Reality na imerzivní náhlavní soupravy. Proto si myslíme, že je důležité ponechat tyto kurzy na místě pro vývojáře, kteří stále hledají pokyny při vývoji těchto zařízení. Tyto kurzy nebudou aktualizovány nejnovějšími sady nástrojů nebo interakcemi používanými pro HoloLens 2. Budou zachovány, aby pokračovaly v práci na podporovaných zařízeních. V budoucnu bude k dispozici nová série kurzů, které předvede vývoj pro HoloLens 2. Toto oznámení bude aktualizováno odkazem na tyto kurzy, když jsou publikovány.


final product -start

V tomto kurzu se dozvíte, jak vytvářet a používat Azure Functions a ukládat data s Azure Storage prostředků v rámci aplikace hybridní reality.

Azure Functions je služba Microsoftu, která vývojářům umožňuje spouštět malé části kódu "functions" v Azure. To nabízí způsob, jak delegovat práci do cloudu, nikoli na místní aplikaci, což může mít mnoho výhod. Azure Functions podporuje několik vývojových jazyků, včetně jazyků C#, F#, Node.js, Java a PHP. Další informace najdete v Azure Functions článku.

Azure Storage cloudová služba Microsoftu, která vývojářům umožňuje ukládat data s pojištěním, že budou vysoce dostupná, zabezpečená, odolná, škálovatelná a redundantní. To znamená, že Microsoft za vás bude řešit všechny problémy související s údržbou a kritickými problémy. Další informace najdete v Azure Storage článku.

Po dokončení tohoto kurzu budete mít aplikaci imerzivní náhlavní soupravy hybridní reality, která dokáže:

  1. Povolí uživateli pohled kolem scény.
  2. Aktivace začátečnění objektů, když uživatel hledí na 3D tlačítko
  3. Objekty, které byly přidány, budou zvoleny funkcí Azure.
  4. Při spuštění každého objektu aplikace uloží typ objektu do souboru Azure,který se nachází v Azure Storage.
  5. Po druhém načtení se načítají data služby Azure File a budou se používat k přehrání akcí při spuštění z předchozí instance aplikace.

V aplikaci je na vás, jak budete integrovat výsledky s vaším návrhem. Tento kurz je navržený tak, aby vás naučil integrovat službu Azure s vaší službou Unity Project. Vaším úkolem je využít znalosti, které získáte z tohoto kurzu, k vylepšení aplikace hybridní reality.

Podpora zařízení

Kurz HoloLens Imerzivní náhlavní soupravy
MR a Azure 305: Funkce a úložiště ✔️ ✔️

Poznámka

I když se tento kurz zaměřuje především Windows Mixed Reality imerzivních náhlavních souprav (VR), můžete také použít to, co se v tomto kurzu naučíte, Microsoft HoloLens. Jak budete postupovat podle kurzu, uvidíte poznámky ke změnám, které možná budete muset použít pro podporu HoloLens.

Požadavky

Poznámka

Tento kurz je určený pro vývojáře, kteří mají základní zkušenosti s Unity a C#. Upozorňujeme také, že požadavky a napsané pokyny v tomto dokumentu představují to, co bylo otestováno a ověřeno v době psaní tohoto dokumentu (květen 2018). Můžete používat nejnovější software, jak je uvedeno v článku o instalaci nástrojů, i když se předpokládá, že informace v tomto kurzu budou dokonale odpovídat informacím, které najdete v novějším softwaru, než je uvedeno níže.

Pro tento kurz doporučujeme následující hardware a software:

Než začnete

Pokud se chcete vyhnout problémům se sestavováním tohoto projektu, důrazně doporučujeme vytvořit projekt uvedený v tomto kurzu v kořenové nebo blízké kořenové složce (dlouhé cesty ke složce mohou způsobit problémy v době sestavení).

1. kapitola – Azure Portal

Pokud chcete použít Azure Storage Service, budete muset vytvořit a nakonfigurovat účet Storage v Azure Portal.

  1. Přihlaste se k webu Azure Portal.

    Poznámka

    Pokud ještě nemáte účet Azure, budete si ho muset vytvořit. Pokud tento kurz postupuje v učebně nebo testovacím prostředí, požádejte o pomoc s nastavením nového účtu instruktora nebo jednoho z kurzů.

  2. Po přihlášení klikněte v levém horním rohu na Nový, vyhledejte Storage účet aklikněte na Enter.

    azure storage search

    Poznámka

    Na novějších portálech může být slovo Nový nahrazenotextem Create a resource (Vytvořit prostředek).

  3. Nová stránka bude zadat popis služby Azure Storage účtu. V levém dolním rohu této výzvy vyberte tlačítko Vytvořit a vytvořte přidružení k této službě.

    vytvoření služby

  4. Po kliknutí na Vytvořit:

    1. Vložte název účtu. Uvědomte si, že toto pole přijímá pouze číslice a malá písmena.

    2. Jako Model nasazenívyberte Resource Manager.

    3. Jako Druh účtuvyberte Storage (obecné účely v1).

    4. Určete umístění vaší skupiny prostředků (pokud vytváříte novou skupinu prostředků). Umístění by v ideálním případě bylo v oblasti, ve které by se aplikace spouštěl. Některé prostředky Azure jsou k dispozici pouze v určitých oblastech.

    5. V možnosti Replikace vyberte Geograficky redundantní úložiště jen pro čtení (RA-GRS).

    6. Výkon – vyberte Standard.

    7. Možnost Požadováno zabezpečeným přenosem ponechte na Zakázáno.

    8. Vyberte předplatné.

    9. Zvolte skupinu prostředků nebo vytvořte novou. Skupina prostředků poskytuje způsob, jak monitorovat, řídit přístup, zřídit a spravovat fakturaci kolekce prostředků Azure. Doporučujeme ponechat všechny služby Azure přidružené k jednomu projektu (například tato testovací prostředí) v rámci společné skupiny prostředků).

      Pokud si chcete přečíst další informace o skupinách prostředků Azure, navštivte prosím článek o skupině prostředků.

    10. Budete také muset potvrdit, že rozumíte podmínkám a podmínkám, které se na tuto službu vztahují.

    11. Vyberte Vytvořit.

      vstupní informace o službě

  5. Po kliknutí na Vytvořitbudete muset počkat, než se služba vytvoří, může to trvat minutu.

  6. Po vytvoření instance služby se na portálu zobrazí oznámení.

    Nové oznámení na webu Azure Portal

  7. Klikněte na oznámení a prozkoumejte novou instanci služby.

    přejít k prostředku

  8. V oznámení klikněte na tlačítko Přejít k prostředku a prozkoumejte novou instanci služby. Budete ve vaší nové instanci služby Storage účtu.

    přístupové klíče

  9. Kliknutím na Přístupovéklíče zobrazíte koncové body pro tuto cloudovou službu. Pomocí Poznámkový blok nebo podobných klíčů zkopírujte jeden z vašich klíčů pro pozdější použití. Poznamenejte si také hodnotu Připojovací řetězec, protože se použije ve třídě AzureServices, kterou vytvoříte později.

    zkopírování připojovacího řetězce

2. kapitola – Nastavení funkce Azure

Teď ve službě Azurenapíšete funkci Azure.

Funkci Azure můžete použít k tomu, abyste mohli prakticky cokoli, co byste měli dělat s klasickými funkcemi v kódu, rozdílem, že k této funkci může přistupovat kterákoli aplikace, která má přihlašovací údaje pro přístup k vašemu účtu Azure.

Vytvoření funkce Azure Functions:

  1. Na webu Azure Portalklikněte v levém horním rohu na nový a vyhledejte Function Appa klikněte na ENTER.

    Vytvoření aplikace Function App

    Poznámka

    Slovo New bylo pravděpodobně nahrazeno vytvořením prostředkuv novějších portálech.

  2. Nová stránka vám poskytne popis služby Azure Function App . V levém dolním rohu této výzvy vyberte tlačítko vytvořit a vytvořte přidružení s touto službou.

    informace o Function App

  3. Po kliknutí na vytvořit:

    1. Zadejte název aplikace. Tady lze použít pouze písmena a číslice (jsou povoleny buď horních, nebo malých písmen).

    2. Vyberte preferované předplatné.

    3. Vyberte skupinu prostředků nebo vytvořte novou. Skupina prostředků nabízí způsob, jak monitorovat, řídit přístup, zřizovat a spravovat fakturace pro kolekci prostředků Azure. Doporučuje se udržovat všechny služby Azure přidružené k jednomu projektu (například k těmto laboratořím) v rámci společné skupiny prostředků.

      Pokud si chcete přečíst další informace o skupinách prostředků Azure, přejděte prosím do článku o skupině prostředků.

    4. pro toto cvičení vyberte Windows jako zvolený operační systém.

    5. Vyberte plán spotřeby pro plán hostování.

    6. Určete umístění pro skupinu prostředků (Pokud vytváříte novou skupinu prostředků). Umístění by v ideálním případě mělo být v oblasti, kde se aplikace spustí. Některé prostředky Azure jsou dostupné jenom v určitých oblastech. Pro zajištění optimálního výkonu vyberte stejnou oblast jako účet úložiště.

    7. v případě Storagevyberte použít existujícía pak pomocí rozevírací nabídky najděte dříve vytvořené úložiště.

    8. u tohoto cvičení nechte Application Insights vypnuto.

      Podrobnosti aplikace vstupní funkce

  4. Klikněte na tlačítko Vytvořit.

  5. Po kliknutí na vytvořitbudete muset počkat na vytvoření služby, což může trvat několik minut.

  6. Po vytvoření instance služby se na portálu zobrazí oznámení.

    oznámení nového portálu Azure Portal

  7. Kliknutím na oznámení můžete prozkoumat novou instanci služby.

    Přejít na aplikaci funkcí prostředků

  8. Kliknutím na tlačítko Přejít k prostředku v oznámení můžete prozkoumat novou instanci služby. Přejdete na novou instanci Function App služby.

  9. Na řídicím panelu Function App najeďte myší na funkce, které se nacházejí v panelu vlevo, a potom klikněte na symbol + (plus) .

    vytvořit novou funkci

  10. Na další stránce se ujistěte, že je vybraná možnost Webhook + API , a pro volbu jazyka vyberte CSharp, protože se jedná o jazyk, který se používá pro tento kurz. Nakonec klikněte na tlačítko vytvořit tuto funkci .

    vybrat CSharp webového zavěšení

  11. Měli byste se přesměrovat na znakovou stránku (Run. csx), pokud ne, klikněte na nově vytvořenou funkci v seznamu funkce v levém panelu.

    otevřít novou funkci

  12. Zkopírujte následující kód do funkce. Tato funkce jednoduše vrátí náhodné celé číslo mezi 0 a 2 při volání. Nedělejte si starosti s existujícím kódem, klidně ho vložte do horní části.

        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. Vyberte Uložit.

  14. Výsledek by měl vypadat jako na obrázku níže.

  15. Klikněte na získat adresu URL funkce a poznamenejte si zobrazenou koncovým bodem . Budete ho muset vložit do třídy AzureServices , kterou vytvoříte později v tomto kurzu.

    Získat koncový bod funkce

    Vložit koncový bod funkce

Kapitola 3 – nastavení projektu Unity

Toto je typická sada pro vývoj se smíšenými realitami a jako taková je dobrá šablona pro jiné projekty.

Nastaví a otestuje moderní sluchátka s poutavými realitami ve smíšeném realitě.

Poznámka

Pro tento kurz nebudete potřebovat řadiče pohybu. Pokud potřebujete podporu s nastavením moderní sluchátka, navštivte prosím smíšený článek o nastavení realit.

  1. Otevřete Unity a klikněte na Nový.

    Vytvořit nový projekt Unity

  2. teď budete muset zadat název Project Unity. Vložit MR_Azure_Functions. Ujistěte se, že je typ projektu nastavený na 3D. Nastavte umístění , které je pro vás vhodné (Nezapomeňte, že blíž ke kořenovým adresářům je lepší). Pak klikněte na vytvořit projekt.

    Zadat název nového projektu Unity

  3. V případě, že je aplikace Unity otevřená, je nutné zkontrolovat, že výchozí Editor skriptů je nastaven na Visual Studio. Přejděte na UpravitPředvolby a pak z nového okna přejděte k externím nástrojům. změňte Editor externích skriptů na Visual Studio 2017. Zavřete okno Předvolby .

    nastavení sady Visual Studio jako editoru skriptů

  4. potom přejděte na souborBuild Nastavení a přepněte platformu na Univerzální platforma Windowskliknutím na tlačítko přepínací platforma .

    Přepnout platformu na UWP

  5. přejít na souborBuild Nastavení a ujistěte se, že:

    1. Cílové zařízení je nastavené na libovolné zařízení.

      v Microsoft HoloLens nastavte cílové zařízení na HoloLens.

    2. Typ sestavení je nastavený na D3D .

    3. Sada SDK je nastavená na nejnovější verzi .

    4. verze Visual Studio je nastavená na nejnovější instalaci .

    5. Sestavení a spuštění je nastaveno na místní počítač .

    6. Uložte scénu a přidejte ji do sestavení.

      1. To uděláte tak, že vyberete Přidat otevřené scény. Zobrazí se okno Uložit.

        Přidat otevřené scény

      2. Vytvořte novou složku pro toto a všechny budoucí, scény a pak vyberte tlačítko Nová složka , abyste vytvořili novou složku, pojmenujte ji na scéně.

        vytvořit složku scény

      3. Otevřete nově vytvořenou složku scény a potom do textového pole název souboru: zadejte FunctionsScenea potom stiskněte Uložit.

        Uložit funkce scény

  6. zbývající nastavení v Nastavení sestaveníby měla být nyní ponechána jako výchozí.

    Ponechat výchozí nastavení sestavení

  7. v okně sestavit Nastavení klikněte na tlačítko Nastavení přehrávače , tím se otevře související panel v prostoru, kde se nachází kontroler .

    nastavení přehrávače v inspektoru

  8. Na tomto panelu je potřeba ověřit několik nastavení:

    1. na druhé kartě Nastavení :

      1. Verze skriptovacího modulu runtime by měla být experimentální (ekvivalent .NET 4,6), která aktivuje nutnost restartovat Editor.
      2. Skriptovací back-end by měl být .NET
      3. Úroveň kompatibility rozhraní API by měla být .NET 4,6 .
    2. na kartě Nastavení publikování v části možnostizaškrtněte:

      • InternetClient

        nastavit možnosti

    3. v dolní části panelu v XR Nastavení (našlo se pod publikováním Nastavení) se podporuje virtuální realitatick, a ujistěte se, že se přidala sada SDK Windows Mixed Reality .

      nastavení XR

  9. Zpět v části NastaveníUnity C# Projekty C# už nejsou zašednuté; zaškrtněte políčko vedle tohoto políčka.

    tick c# projects

  10. Zavřete okno Nastavení sestavení.

  11. Uložte scénu a Project(SOUBORSAVE SCENE / FILESAVE PROJECT).

4. kapitola – Nastavení hlavní kamery

Důležité

Pokud chcete přeskočit komponenty Unity Set up tohoto kurzu a pokračovat přímo do kódu, stáhněte si tento balíček .unitypackagea naimportujte ho do svého projektu jako vlastní balíček. Bude také obsahovat knihovny DLL z další kapitoly. Po importu pokračujte od 7. kapitoly.

  1. Na panelu Hierarchienajdete objekt s názvem Hlavníkamera , který představuje "hlavní" pohled, jakmile budete uvnitř aplikace.

  2. S řídicím panelem Unity před vás vyberte GameObject hlavní kamery. Všimněte si, že panel inspektoru (obecně nalezený napravo na řídicím panelu) zobrazí různé komponenty tohoto objektu GameObjects možností Transformovat v horní části, za kterou následuje Fotoaparát a některé další komponenty. Budete muset resetovat transformaci hlavní kamery, aby byla správně umístěná.

  3. Chcete-li to provést, vyberte ikonu ozubeného kola vedle komponenty Transformace fotoaparátu a vyberte Resetovat.

    resetování transformace

  4. Potom aktualizujte komponentu Transform (Transformace), aby vypadala podobně jako tato:

    TRANSFORMACE – POZICE
    X Y Z
    0 1 0
    TRANSFORMACE – ROTACE
    X Y Z
    0 0 0
    TRANSFORMACE – ŠKÁLOVÁNÍ
    X Y Z
    1 1 1

    nastavení transformace fotoaparátu

5. kapitola – Nastavení scény Unity

  1. Klikněte pravým tlačítkem do prázdné oblasti panelu Hierarchiev části 3D Objekta přidejte rovinu.

    vytvoření nové roviny

  2. Vyberte objekt Plane (Rovina) a v panelu inspektoru změňte následující parametry:

    TRANSFORMACE – POZICE
    X Y Z
    0 0 4
    TRANSFORMACE – ŠKÁLOVÁNÍ
    X Y Z
    10 1 10

    nastavení pozice a škálování roviny

    zobrazení scény roviny

  3. Klikněte pravým tlačítkem do prázdné oblasti panelu Hierarchiev části 3D Objekta přidejte datovou krychli.

    1. Přejmenujte datovou krychli na GazeButton (s vybranou datovou krychlí a stisknutím klávesy F2).

    2. Na panelu inspektoru změňte následující parametry:

      TRANSFORMACE – POZICE
      X Y Z
      0 3 5

      nastavení transformace tlačítka pohledu

      zobrazení scény s tlačítkem pohledu

    3. Klikněte na rozevírací tlačítko Značka a kliknutím na Přidat značku otevřete podokno Vrstvy značek.

      přidání nové značky

      Výběr možnosti plus

    4. Vyberte tlačítko + (plus) a do pole New Tag Name (Nový název značky) zadejte GazeButtona stiskněte Save (Uložit).

      název nové značky

    5. V hierarchickém panelu klikněte na objekt GazeButton a na panelu inspektoru přiřaďte nově vytvořenou značku GazeButton.

      Přiřazení tlačítka pro pohled k nové značce

  4. Klikněte pravým tlačítkem na objekt GazeButton v hierarchickém panelua přidejte prázdný objekt GameObject (který se přidá jako podřízený objekt).

  5. Vyberte nový objekt a přejmenujte ho na ShapeSpawnPoint.

    1. Na panelu inspektoru změňte následující parametry:

      TRANSFORMACE – POZICE
      X Y Z
      0 -1 0

      Aktualizace transformace bodu spawn pointu obrazce

      zobrazení scény bodu nátvaru obrazce

  6. Dále vytvoříte objekt 3D Text, který vám poskytne zpětnou vazbu ke stavu služby Azure.

    Znovu klikněte pravým tlačítkem na tlačítko GazeButton v hierarchickém panelu a přidejte objekt 3D Object3D Text jako podřízený objekt.

    vytvoření nového 3D textového objektu

  7. Přejmenujte objekt 3D Text na AzureStatusText.

  8. Změňte transformaci objektu AzureStatusText následujícím způsobem:

    TRANSFORMACE – POZICE
    X Y Z
    0 0 -0.6
    TRANSFORMACE – ŠKÁLOVÁNÍ
    X Y Z
    0.1 0.1 0.1

    Poznámka

    Nedělejte si starosti, pokud se zdá, že je mimo centrum, protože tato chyba bude opravena při aktualizaci následující komponenty Text Mesh.

  9. Změňte komponentu Text Mesh tak, aby odpovídala následujícímu:

    nastavení komponenty textové sítě

    Tip

    Vybraná barva je Šestnáctová barva: 000000FF.Můžete si ale zvolit svou vlastní, jen se ujistěte, že je čitelná.

  10. Struktura panelu Hierarchie by teď měla vypadat takhle:

    Textová síť v hierarchii

  11. Vaše scéna by teď měla vypadat takhle:

    Textová síť v zobrazení scény

6. kapitola – import Azure Storage pro Unity

Budete používat sadu Azure Storage pro Unity (která sama využívá sadu .NET SDK pro Azure). Další informace si můžete přečíst v článku Azure Storage pro Unity.

V Unity aktuálně existuje známý problém, který vyžaduje, aby po importu byly moduly plug-in překonfigurované. Tyto kroky (4 až 7 v této části) už nebudou po vyřešení chyby potřeba.

Pokud chcete importovat sadu SDK do vlastního projektu, ujistěte se, že jste si stáhli nejnovější soubor .unitypackage z GitHub. Pak proveďte tyto akce:

  1. Pomocí možnosti nabídky Vlastní balíček importu prostředků přidejte soubor .unitypackage do Unity.

  2. V automaticky otevíraného okně Import Unity Package (Importovat balíček Unity) můžete vybrat všechno v části PluginStorage. Zrušte zaškrtnutí všech jinam, protože to pro tento kurz není potřeba.

    import do balíčku

  3. Kliknutím na tlačítko Importovat přidejte položky do projektu.

  4. Přejděte do složky Storage v části Moduly plug-inv zobrazení Project a vyberte pouze následující moduly plug-in:

    • Microsoft.Data.Edm

    • Microsoft.Data.OData

    • Microsoft.WindowsAzure.Storage

    • Newtonsoft.Json

    • System.Spatial

      zrušte zaškrtnutí políčka Libovolná platforma.

  5. Když máte vybrané tyto konkrétní moduly plug-in,zrušte zaškrtnutípolíčkaLibovolná platforma a zrušte zaškrtnutípolíčkaWSAPlayer a klikněte na Použít.

    použití knihoven DLL platformy

    Poznámka

    Tyto konkrétní moduly plug-in označme tak, aby se používaly pouze v Editoru Unity. Je to proto, že ve složce WSA existují různé verze stejných modulů plug-in, které se budou používat po exportu projektu z Unity.

  6. Ve složce Storage plug-in vyberte pouze:

    • Microsoft.Data.Services.Client

      nastavení nezpracuje knihovny DLL

  7. V části Platforma zaškrtněte políčko Nezpracujtea klikněte Nastavenípoužít.

    použití bez zpracování

    Poznámka

    Tento modul plug-in označme jako "Nezpracování", protože oprava sestavení Unity má potíže se zpracováním tohoto modulu plug-in. Modul plug-in bude fungovat i v případě, že se nezpracuje.

7. kapitola – Vytvoření třídy AzureServices

První třídou, kterou budete vytvářet, je třída AzureServices.

Za:

  • Ukládání přihlašovacích údajů k účtu Azure

  • Volání funkce aplikace Azure

  • Nahrání a stažení datového souboru v Azure Cloud Storage.

Vytvoření této třídy:

  1. Klikněte pravým tlačítkem do složky assetu, která se nachází v Project panelu Vytvořitsložku. Složku pojmechte Scripts (Skripty).

    vytvoření nové složky

    složka call – skripty

  2. Poklikejte na právě vytvořenou složku a otevřete ji.

  3. Klikněte pravým tlačítkem do složky CreateC# Script (Vytvořit skript jazyka C#). Volejte skript AzureServices.

  4. Dvojím kliknutím na novou třídu AzureServices ji otevřete pomocí Visual Studio.

  5. Na začátek AzureServices přidejte následující obory názvů:

        using System;
        using System.Threading.Tasks;
        using UnityEngine;
        using Microsoft.WindowsAzure.Storage;
        using Microsoft.WindowsAzure.Storage.File;
        using System.IO;
        using System.Net;
    
  6. Do třídy AzureServices přidejte následující pole inspektoru:

        /// <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. Pak do třídy AzureServices přidejte následující členské proměnné:

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

    Důležité

    Nezapomeňte nahradit hodnoty koncového bodu a připojovacího řetězce hodnotami z úložiště Azure, které najdete na webu Azure Portal.

  8. Teď je potřeba přidat kód pro metody Awake() a Start(). Tyto metody budou volány při inicializaci třídy:

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

    Důležité

    Kód pro CallAzureFunctionForNextShape() vyplníme v budoucí kapitole.

  9. Odstraňte metodu Update(), protože ji tato třída nebude používat.

  10. Uložte změny v Visual Studio a pak se vraťte do Unity.

  11. Klikněte na třídu AzureServices a přetáhněte ji ze složky Skripty do objektu Hlavní kamera v hierarchickém panelu.

  12. Vyberte hlavní kameru, potom zminěte podřízený objekt AzureStatusText pod objektEm GazeButton a umístěte ho do pole referenčního cíle AzureStatusText v inspektorua zadejte odkaz na skript AzureServices.

    přiřazení referenčního odkazu na text stavu Azure

8. kapitola – vytvoření třídy ShapeFactory

Dalším skriptem, který se má vytvořit, je třída ShapeFactory. Role této třídy je vytvoření nového tvaru na vyžádání a historie tvarů vytvořených v seznamu historie obrazců. Při každém vytvoření obrazce se seznam Historie obrazce aktualizuje ve třídě AzureService a pak se uloží do Azure Storage. Pokud se při spuštění aplikace v souboru Azure Storagenachází uložený soubor, načte se a znovu přehrá seznam Historie obrazce s objektem 3D Text, který určuje, jestli vygenerovaný tvar pochází z úložiště, nebo nový.

Vytvoření této třídy:

  1. Přejděte do složky Scripts, kterou jste vytvořili dříve.

  2. Klikněte pravým tlačítkem do složky CreateC# Script (Vytvořit skript jazyka C#). Volejte skript ShapeFactory.

  3. Dvojím kliknutím na nový skript ShapeFactory ho otevřete pomocí Visual Studio.

  4. Ujistěte se, že třída ShapeFactory obsahuje následující obory názvů:

        using System.Collections.Generic;
        using UnityEngine;
    
  5. Přidejte níže uvedené proměnné do třídy ShapeFactory a nahraďte funkce Start() a Awake() následujícími funkcemi:

        /// <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. Metoda CreateShape() generuje primitivní tvary na základě poskytnutého celočíselného parametru. Logický parametr se používá k určení, jestli aktuálně vytvořený tvar pochází z úložiště, nebo z nového. Do třídy ShapeFactory umístěte následující kód pod předchozí metody:

        /// <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. Než se vrátíte do Unity, nezapomeňte změny uložit v Visual Studio.

  8. Zpět v editoru Unity klikněte na třídu ShapeFactory a přetáhněte ji ze složky Scripts do objektu Hlavní kamera v hierarchickém panelu.

  9. Když vyberete hlavní kameru, všimnete si, že komponentě skriptu ShapeFactory chybí odkaz Spawn Point (Bod spawn). Opravíte ho tak, že přetáhnete objekt ShapeSpawnPoint z panelu Hierarchie do cílového odkazu Spawn Point.

    nastavení referenčního cíle objektu pro vytváření obrazce

Kapitola 9 – vytvoření třídy Pohled

Posledním skriptem, který musíte vytvořit, je třída Pohled.

Tato třída zodpovídá za vytvoření paprskového vysílání, které bude promítáno z hlavní kamery, aby bylo možné zjistit, na který objekt se uživatel dívá. V takovém případě bude Raycast muset zjistit, jestli se uživatel dívá na objekt GazeButton ve scéně a aktivuje chování.

Vytvoření této třídy:

  1. Přejděte do složky Scripts, kterou jste vytvořili dříve.

  2. Klikněte pravým tlačítkem na panel Project, Create C# Script (Vytvořitskript C#). Volejte skript Pohled .

  3. Dvojím kliknutím na nový skript Pohled ho otevřete pomocí Visual Studio.

  4. Ujistěte se, že je v horní části skriptu zahrnutý následující obor názvů:

        using UnityEngine;
    
  5. Pak přidejte následující proměnné do třídy 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;
    

Důležité

Některé z těchto proměnných bude možné upravovat v editoru.

  1. Teď je potřeba přidat kód pro metody Awake() a Start().

        /// <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. Přidejte následující kód, který vytvoří objekt kurzoru na začátku, společně s metodou Update(), která spustí metodu Raycast, společně s tím, kde je přepínací logická hodnota GazeEnabled:

        /// <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. Dále přidejte metodu UpdateRaycast(), která promítá Raycast a detekuje cíl hitu.

        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. Nakonec přidejte metodu ResetFocusedObject(), která přepne aktuální barvu objektů GazeButton, která určuje, jestli vytváří nový tvar nebo ne.

        /// <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. Než se vrátíte do Unity, Visual Studio změny uložte v souboru .

  6. Klikněte na třídu Pohled a přetáhněte ji ze složky Skripty do objektu Hlavní kamera v hierarchickém panelu.

Kapitola 10 – Dokončení třídy AzureServices

Když jsou k dispozici další skripty, je teď možné dokončit tříduAzureServices. Toho dosáhnete prostřednictvím:

  1. Přidáním nové metody s názvem CreateCloudIdentityAsync()nastavíte proměnné ověřování potřebné pro komunikaci s Azure.

    Tato metoda také zkontroluje existenci dříve uloženého souboru obsahujícího seznam obrazců.

    Pokud se soubor nachází, zakáže uživateli pohled a aktivuje vytvoření obrazce podle vzoru tvarů uloženého v Azure Storage souboru. Uživatel to uvidí, protože textová síť v závislosti na původu tvarů Storage zobrazí text "Storage" nebo "Nový".

    Pokud se žádný soubor nenašel,povolí pohleda umožní uživateli vytvářet obrazce při pohledu na objekt GazeButton ve scéně.

        /// <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. Další fragment kódu pochází z metody Start(). Kde bude provedeno volání metody CreateCloudIdentityAsync(). Můžete si zkopírovat aktuální metodu Start() s následujícími možnostmi:

        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. Vyplňte kód pro metodu CallAzureFunctionForNextShape(). K vyžádání indexu obrazce použijete dříve vytvořenou aplikaci Azure Function App. Po přijetí nového tvaru tato metoda odešle tvar do třídy ShapeFactory, aby se ve scéně vytvořil nový tvar. Pomocí následujícího kódu dokončete tělo metody 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. Přidejte metodu pro vytvoření řetězce tak, že zřetězíte celá čísla uložená v seznamu historie obrazců a uložíte ho do 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. Přidejte metodu pro načtení textu uloženého v souboru umístěném v souboru Azure Storage File a deserializaci do seznamu.

  6. Po dokončení tohoto procesu metoda znovu povolí pohled, aby uživatel mohl do scény přidat další obrazce.

        ///<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. Než se vrátíte do Unity, Visual Studio změny uložte v souboru .

11. kapitola – Sestavení řešení pro UPW

Zahájení procesu sestavení:

  1. Přejděte na Souborsestavení Nastavení.

    sestavení aplikace

  2. Klikněte na Build (Sestavit). Unity spustí Průzkumník souborů, ve kterém budete muset vytvořit a pak vybrat složku, do které chcete aplikaci sestavit. Teď vytvořte složku a pojmnte ji App (Aplikace). Potom s vybranou možností Složka aplikace stiskněte Vybrat složku.

  3. Unity začne vytvářet projekt do složky App.

  4. Jakmile Unity dokončí sestavování (může to chvíli trvat), otevře se v umístění sestavení okno Průzkumník souborů (podívejte se na hlavní panel, protože se nemusí vždy zobrazovat nad okny, ale upozorní vás na přidání nového okna).

12. kapitola – Nasazení aplikace

Nasazení aplikace:

  1. Přejděte do složky Aplikace, která byla vytvořena v poslední kapitole. Zobrazí se soubor s názvem vaší aplikace s příponou .sln, na který byste měli dvakrát kliknout, takže ho otevřete v rámci Visual Studio.

  2. V platformě řešenívyberte x86, místní počítač.

  3. V části Konfigurace řešení vyberte Ladit.

    Pro Microsoft HoloLens může být jednodušší ji nastavit na Vzdálený počítač,abyste se k počítači nevázáni. Budete ale muset provést také následující akce:

    • Znát IP adresu vašeho HoloLens, kterou najdete v rozšířených možnostech Wi-Fi sítě Nastavení Network ; IPv4 je adresa, kterou byste měli použít.
    • Ujistěte se, že je vývojářskýrežim v provozu. najdete v NastaveníUpdate Securitypro vývojáře.

    nasazení řešení

  4. Přejděte do nabídky Build (Sestavení) a kliknutím na Deploy Solution (Nasadit řešení) aplikaci nasadíte do počítače bokem.

  5. Vaše aplikace by se teď měla zobrazit v seznamu nainstalovaných aplikací připravených ke spuštění a otestování.

Hotová Azure Functions Storage aplikace

Blahopřejeme, máte vytvořenou aplikaci hybridní reality, která využívá Azure Functions i Azure Storage služby. Vaše aplikace bude moct na základě uložených dat kreslit uložená data a poskytovat akci.

final product -end

Bonusová cvičení

Cvičení 1

Vytvořte druhý bod spawn a záznam, ze kterého byl vytvořen objekt. Při načítání datového souboru znovu přehrajte tvary vytvořené z místa, kde byly původně vytvořeny.

Cvičení 2

Vytvořte způsob, jak aplikaci restartovat, místo abyste ji pokaždé museli znovu otevírat. Načítání scén je vhodné začít. Potom vytvořte způsob, jak vymazat uložený seznam v Azure Storage, abyste ho mohli z aplikace snadno resetovat.