Observação

Os tutoriais do Mixed Reality Academy foram projetados com o HoloLens (1ª geração) e os headsets imersivos de realidade misturada em mente.The Mixed Reality Academy tutorials were designed with HoloLens (1st gen) and Mixed Reality Immersive Headsets in mind. Dessa forma, achamos que é importante continuar disponibilizando esses tutoriais para os desenvolvedores que ainda buscam obter diretrizes para o desenvolvimento visando esses dispositivos.As such, we feel it is important to leave these tutorials in place for developers who are still looking for guidance in developing for those devices. Esses tutoriais não serão atualizados com os conjuntos de ferramentas mais recentes nem com as interações usadas para o HoloLens 2.These tutorials will not be updated with the latest toolsets or interactions being used for HoloLens 2. Eles serão mantidos para continuar funcionando nos dispositivos compatíveis.They will be maintained to continue working on the supported devices. Haverá uma nova série de tutoriais que serão publicados no futuro, que demonstrarão como desenvolver para o HoloLens 2.There will be a new series of tutorials that will be posted in the future that will demonstrate how to develop for HoloLens 2. Esse aviso será atualizado com um link para esses tutoriais quando eles forem postados.This notice will be updated with a link to those tutorials when they are posted.


Sr e Azure 305: funções e armazenamentoMR and Azure 305: Functions and storage

início do produto final

Neste curso, você aprenderá a criar e usar Azure Functions e armazenar dados com um recurso de armazenamento do Azure, em um aplicativo de realidade misturada.In this course, you will learn how to create and use Azure Functions and store data with an Azure Storage resource, within a mixed reality application.

Azure Functions é um serviço da Microsoft, que permite aos desenvolvedores executar pequenas partes de código, ' Functions ', no Azure.Azure Functions is a Microsoft service, which allows developers to run small pieces of code, 'functions', in Azure. Isso fornece uma maneira de delegar trabalho para a nuvem, em vez de seu aplicativo local, que pode ter muitos benefícios.This provides a way to delegate work to the cloud, rather than your local application, which can have many benefits. O Azure Functions dá suporte a várias linguagens de desenvolvimento, incluindo C#, F#, Node. js, Java e php.Azure Functions supports several development languages, including C#, F#, Node.js, Java, and PHP. Para obter mais informações, visite o artigo Azure Functions.For more information, visit the Azure Functions article.

O armazenamento do Azure é um serviço de nuvem da Microsoft, que permite aos desenvolvedores armazenar dados, com o seguro de que ele será altamente disponível, seguro, durável, escalonável e redundante.Azure Storage is a Microsoft cloud service, which allows developers to store data, with the insurance that it will be highly available, secure, durable, scalable, and redundant. Isso significa que a Microsoft tratará de toda a manutenção e problemas críticos para você.This means Microsoft will handle all maintenance, and critical problems for you. Para obter mais informações, visite o artigo armazenamento do Azure.For more information, visit the Azure Storage article.

Após concluir este curso, você terá um aplicativo de headset de imersão de realidade misturada que poderá fazer o seguinte:Having completed this course, you will have a mixed reality immersive headset application which will be able to do the following:

  1. Permitir que o usuário olhar em uma cena.Allow the user to gaze around a scene.
  2. Dispare a geração de objetos quando o usuário gazes em um "botão" 3D.Trigger the spawning of objects when the user gazes at a 3D 'button'.
  3. Os objetos gerados serão escolhidos por uma função do Azure.The spawned objects will be chosen by an Azure Function.
  4. À medida que cada objeto é gerado, o aplicativo armazenará o tipo de objeto em um arquivo do Azure, localizado no armazenamento do Azure.As each object is spawned, the application will store the object type in an Azure File, located in Azure Storage.
  5. Ao carregar uma segunda vez, os dados de arquivo do Azure serão recuperados e usados para reproduzir as ações de geração da instância anterior do aplicativo.Upon loading a second time, the Azure File data will be retrieved, and used to replay the spawning actions from the previous instance of the application.

Em seu aplicativo, cabe a você como você integrará os resultados com seu design.In your application, it is up to you as to how you will integrate the results with your design. Este curso foi projetado para ensinar a você como integrar um serviço do Azure com seu projeto do Unity.This course is designed to teach you how to integrate an Azure Service with your Unity Project. É seu trabalho usar o conhecimento obtido deste curso para aprimorar seu aplicativo de realidade misturada.It is your job to use the knowledge you gain from this course to enhance your mixed reality Application.

Suporte a dispositivosDevice support

CursoCourse HoloLensHoloLens Headsets imersivosImmersive headsets
Sr e Azure 305: funções e armazenamentoMR and Azure 305: Functions and storage ✔️✔️ ✔️✔️

Observação

Embora este curso se concentre principalmente em fones de ouvido (VR) de realidade mista do Windows, você também pode aplicar o que aprende neste curso ao Microsoft HoloLens.While this course primarily focuses on Windows Mixed Reality immersive (VR) headsets, you can also apply what you learn in this course to Microsoft HoloLens. Ao acompanhar o curso, você verá observações sobre as alterações que talvez precise empregar para dar suporte ao HoloLens.As you follow along with the course, you will see notes on any changes you might need to employ to support HoloLens.

{1>{2>Pré-requisitos<2}<1}Prerequisites

Observação

Este tutorial foi desenvolvido para desenvolvedores que têm experiência básica com o Unity C#e o.This tutorial is designed for developers who have basic experience with Unity and C#. Além disso, lembre-se de que os pré-requisitos e as instruções escritas neste documento representam o que foi testado e verificado no momento da gravação (maio de 2018).Please also be aware that the prerequisites and written instructions within this document represent what has been tested and verified at the time of writing (May 2018). Você está livre para usar o software mais recente, conforme listado no artigo instalar as ferramentas , embora não seja recomendável que as informações neste curso irão se adequar perfeitamente ao que você encontrará em softwares mais recentes do que as listadas abaixo.You are free to use the latest software, as listed within the install the tools article, though it should not be assumed that the information in this course will perfectly match what you'll find in newer software than what's listed below.

Recomendamos o seguinte hardware e software para este curso:We recommend the following hardware and software for this course:

Antes de começarBefore you start

Para evitar problemas de criação desse projeto, é altamente recomendável que você crie o projeto mencionado neste tutorial em uma pasta raiz ou quase raiz (caminhos de pasta longos podem causar problemas em tempo de compilação).To avoid encountering issues building this project, it is strongly suggested that you create the project mentioned in this tutorial in a root or near-root folder (long folder paths can cause issues at build-time).

Capítulo 1-o portal do AzureChapter 1 - The Azure Portal

Para usar o serviço de armazenamento do Azure, você precisará criar e configurar uma conta de armazenamento no portal do Azure.To use the Azure Storage Service, you will need to create and configure a Storage Account in the Azure portal.

  1. Faça logon no portal do Azure.Log in to the Azure Portal.

    Observação

    Se você ainda não tiver uma conta do Azure, será necessário criar uma.If you do not already have an Azure account, you will need to create one. Se você estiver seguindo este tutorial em uma situação de sala de aula ou laboratório, peça ao instrutor ou a uma das proctors para obter ajuda para configurar sua nova conta.If you are following this tutorial in a classroom or lab situation, ask your instructor or one of the proctors for help setting up your new account.

  2. Depois de fazer logon, clique em novo no canto superior esquerdo e procure conta de armazenamentoe clique em Enter.Once you are logged in, click on New in the top left corner, and search for Storage account, and click Enter.

    pesquisa de armazenamento do Azure

    Observação

    A palavra novo pode ter sido substituída por criar um recurso, em portais mais recentes.The word New may have been replaced with Create a resource, in newer portals.

  3. A nova página fornecerá uma descrição do serviço de conta de armazenamento do Azure .The new page will provide a description of the Azure Storage account service. Na parte inferior esquerda desse prompt, selecione o botão criar para criar uma associação com esse serviço.At the bottom left of this prompt, select the Create button, to create an association with this service.

    Criar serviço

  4. Depois de clicar em criar:Once you have clicked on Create:

    1. Insira um nome para sua conta, lembre-se de que esse campo aceita apenas números e letras minúsculas.Insert a Name for your account, be aware this field only accepts numbers, and lowercase letters.

    2. Para modelo de implantação, selecione Gerenciador de recursos.For Deployment model, select Resource manager.

    3. Para tipo de conta, selecione armazenamento (uso geral v1) .For Account kind, select Storage (general purpose v1).

    4. Determine o local do seu grupo de recursos (se você estiver criando um novo grupo de recursos).Determine the Location for your resource group (if you are creating a new Resource Group). O local ideal seria na região em que o aplicativo seria executado.The location would ideally be in the region where the application would run. Alguns ativos do Azure só estão disponíveis em determinadas regiões.Some Azure assets are only available in certain regions.

    5. Para replicação , selecione leitura-acesso-armazenamento com REDUNDÂNCIA geográfica (ra-grs) .For Replication select Read-access-geo-redundant storage (RA-GRS).

    6. Para desempenho, selecione padrão.For Performance, select Standard.

    7. Deixe a transferência segura necessária como desabilitada.Leave Secure transfer required as Disabled.

    8. Selecione uma assinatura.Select a Subscription.

    9. Escolha um grupo de recursos ou crie um novo.Choose a Resource Group or create a new one. Um grupo de recursos fornece uma maneira de monitorar, controlar o acesso, provisionar e gerenciar a cobrança de uma coleção de ativos do Azure.A resource group provides a way to monitor, control access, provision and manage billing for a collection of Azure assets. É recomendável manter todos os serviços do Azure associados a um único projeto (por exemplo, esses laboratórios) em um grupo de recursos comum).It is recommended to keep all the Azure services associated with a single project (e.g. such as these labs) under a common resource group).

      Se você quiser ler mais sobre grupos de recursos do Azure, visite o artigo grupo de recursos.If you wish to read more about Azure Resource Groups, please visit the resource group article.

    10. Você também precisará confirmar que entendeu os termos e condições aplicados a esse serviço.You will also need to confirm that you have understood the Terms and Conditions applied to this Service.

    11. Selecione Criar.Select Create.

      informações do serviço de entrada

  5. Depois de clicar em criar, você precisará aguardar até que o serviço seja criado, isso pode levar um minuto.Once you have clicked on Create, you will have to wait for the service to be created, this might take a minute.

  6. Uma notificação será exibida no portal assim que a instância do serviço for criada.A notification will appear in the portal once the Service instance is created.

    Nova notificação no portal do Azure

  7. Clique nas notificações para explorar sua nova instância de serviço.Click on the notifications to explore your new Service instance.

    ir para o recurso

  8. Clique no botão ir para recurso na notificação para explorar sua nova instância de serviço.Click the Go to resource button in the notification to explore your new Service instance. Você será levado para sua nova instância de serviço da conta de armazenamento .You will be taken to your new Storage account service instance.

    teclas de acesso

  9. Clique em chaves de acessopara revelar os pontos de extremidade para este serviço de nuvem.Click Access keys, to reveal the endpoints for this cloud service. Use o bloco de notas ou semelhante para copiar uma de suas chaves para uso posterior.Use Notepad or similar, to copy one of your keys for use later. Além disso, observe o valor da cadeia de conexão , pois ele será usado na classe azureservices , que será criada mais tarde.Also, note the Connection string value, as it will be used in the AzureServices class, which you will create later.

    copiar cadeia de conexão

Capítulo 2-Configurando uma função do AzureChapter 2 - Setting up an Azure Function

Agora, você escreverá uma função do Azure no serviço do Azure.You will now write an Azure Function in the Azure Service.

Você pode usar uma função do Azure para fazer praticamente tudo o que faria com uma função clássica em seu código, a diferença é que essa função pode ser acessada por qualquer aplicativo que tenha credenciais para acessar sua conta do Azure.You can use an Azure Function to do nearly anything that you would do with a classic function in your code, the difference being that this function can be accessed by any application that has credentials to access your Azure Account.

Para criar uma função do Azure:To create an Azure Function:

  1. No portal do Azure, clique em novo no canto superior esquerdo e procure aplicativo de funçõese clique em Enter.From your Azure Portal, click on New in the top left corner, and search for Function App, and click Enter.

    criar aplicativo de funções

    Observação

    A palavra novo pode ter sido substituída por criar um recurso, em portais mais recentes.The word New may have been replaced with Create a resource, in newer portals.

  2. A nova página fornecerá uma descrição do serviço de aplicativo de funções do Azure .The new page will provide a description of the Azure Function App service. Na parte inferior esquerda desse prompt, selecione o botão criar para criar uma associação com esse serviço.At the bottom left of this prompt, select the Create button, to create an association with this service.

    informações do aplicativo de funções

  3. Depois de clicar em criar:Once you have clicked on Create:

    1. Forneça um nome de aplicativo.Provide an App name. Somente letras e números podem ser usados aqui (é permitido um caso superior ou inferior).Only letters and numbers can be used here (either upper or lower case is allowed).

    2. Selecione sua assinaturapreferida.Select your preferred Subscription.

    3. Escolha um grupo de recursos ou crie um novo.Choose a Resource Group or create a new one. Um grupo de recursos fornece uma maneira de monitorar, controlar o acesso, provisionar e gerenciar a cobrança de uma coleção de ativos do Azure.A resource group provides a way to monitor, control access, provision and manage billing for a collection of Azure assets. É recomendável manter todos os serviços do Azure associados a um único projeto (por exemplo, esses laboratórios) em um grupo de recursos comum).It is recommended to keep all the Azure services associated with a single project (e.g. such as these labs) under a common resource group).

      Se você quiser ler mais sobre grupos de recursos do Azure, visite o artigo grupo de recursos.If you wish to read more about Azure Resource Groups, please visit the resource group article.

    4. Para este exercício, selecione Windows como o sistema operacionalescolhido.For this exercise, select Windows as the chosen OS.

    5. Selecione plano de consumo para o plano de hospedagem.Select Consumption Plan for the Hosting Plan.

    6. Determine o local do seu grupo de recursos (se você estiver criando um novo grupo de recursos).Determine the Location for your resource group (if you are creating a new Resource Group). O local ideal seria na região em que o aplicativo seria executado.The location would ideally be in the region where the application would run. Alguns ativos do Azure só estão disponíveis em determinadas regiões.Some Azure assets are only available in certain regions. Para obter um desempenho ideal, selecione a mesma região que a conta de armazenamento.For optimal performance, select the same region as the storage account.

    7. Para armazenamento, selecione usar existentee, em seguida, usando o menu suspenso, localize o armazenamento criado anteriormente.For Storage, select Use existing, and then using the dropdown menu, find your previously created storage.

    8. Deixe Application insights desativado para este exercício.Leave Application Insights off for this exercise.

      detalhes do aplicativo de função de entrada

  4. Clique no botão Criar.Click the Create button.

  5. Depois de clicar em criar, você precisará aguardar até que o serviço seja criado, isso pode levar um minuto.Once you have clicked on Create, you will have to wait for the service to be created, this might take a minute.

  6. Uma notificação será exibida no portal assim que a instância do serviço for criada.A notification will appear in the portal once the Service instance is created.

    Nova notificação do portal do Azure

  7. Clique nas notificações para explorar sua nova instância de serviço.Click on the notifications to explore your new Service instance.

    ir para o aplicativo de função de recurso

  8. Clique no botão ir para recurso na notificação para explorar sua nova instância de serviço.Click the Go to resource button in the notification to explore your new Service instance. Você será levado para sua nova instância do serviço aplicativo de funções .You will be taken to your new Function App service instance.

  9. No painel aplicativo de funções , passe o mouse sobre as funções, localizadas no painel à esquerda e clique no símbolo + (mais) .On the Function App dashboard, hover your mouse over Functions, found within the panel on the left, and then click the + (plus) symbol.

    criar nova função

  10. Na página seguinte, verifique se webhook + API está selecionado e, para escolher um idioma, selecione Csharp, pois esse será o idioma usado para este tutorial.On the next page, ensure Webhook + API is selected, and for Choose a language, select CSharp, as this will be the language used for this tutorial. Por fim, clique no botão criar esta função .Lastly, click the Create this function button.

    selecionar o Web Hook Csharp

  11. Você deve ser levado para a página de código (Run. CSX), se não estiver, clique na função recém-criada na lista de funções no painel à esquerda.You should be taken to the code page (run.csx), if not though, click on the newly created Function in the Functions list within the panel on the left.

    abrir nova função

  12. Copie o código a seguir em sua função.Copy the following code into your function. Essa função simplesmente retornará um inteiro aleatório entre 0 e 2, quando chamado.This function will simply return a random integer between 0 and 2 when called. Não se preocupe com o código existente, fique à vontade para colar na parte superior.Do not worry about the existing code, feel free to paste over the top of it.

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

  14. O resultado deve ser semelhante à imagem abaixo.The result should look like the image below.

  15. Clique em obter URL da função e anote o ponto de extremidade exibido.Click on Get function URL and take note of the endpoint displayed. Você precisará inseri-lo na classe azureservices que será criada posteriormente neste curso.You will need to insert it into the AzureServices class that you will create later in this course.

    obter ponto de extremidade de função

    obter ponto de extremidade de função

Capítulo 3-Configurando o projeto do UnityChapter 3 - Setting up the Unity project

A seguir está uma configuração típica para o desenvolvimento com realidade misturada e, como tal, é um bom modelo para outros projetos.The following is a typical set up for developing with Mixed Reality, and as such, is a good template for other projects.

Configure e teste seu headset de imersão de realidade misturada.Set up and test your mixed reality immersive headset.

Observação

Você não precisará de controladores de animação para este curso.You will not require Motion Controllers for this course. Se você precisar de suporte para configurar o headset de imersão, visite o artigo configuração de realidade misturada.If you need support setting up the immersive headset, please visit the mixed reality set up article.

  1. Abra o Unity e clique em novo.Open Unity and click New.

    criar novo projeto de Unity

  2. Agora, você precisará fornecer um nome de projeto de Unity.You will now need to provide a Unity Project name. Inserir MR_Azure_Functions.Insert MR_Azure_Functions. Verifique se o tipo de projeto está definido como 3D.Make sure the project type is set to 3D. Defina o local como algum lugar apropriado para você (Lembre-se de que, mais próximo de diretórios raiz é melhor).Set the Location to somewhere appropriate for you (remember, closer to root directories is better). Em seguida, clique em criar projeto.Then, click Create project.

    Dê um nome ao novo projeto do Unity

  3. Com o Unity Open, vale a pena verificar se o Editor de script padrão está definido como Visual Studio.With Unity open, it is worth checking the default Script Editor is set to Visual Studio. Vá para Editar preferências de > e, em seguida, na nova janela, navegue até Ferramentas externas.Go to Edit > Preferences and then from the new window, navigate to External Tools. Altere o Editor de script externo para o Visual Studio 2017.Change External Script Editor to Visual Studio 2017. Feche a janela preferências .Close the Preferences window.

    definir o Visual Studio como editor de script

  4. Em seguida, vá para arquivo > configurações de Build e alterne a plataforma para plataforma universal do Windowsclicando no botão alternar plataforma .Next, go to File > Build Settings and switch the platform to Universal Windows Platform, by clicking on the Switch Platform button.

    alternar plataforma para UWP

  5. Vá para arquivo > configurações de compilação e verifique se:Go to File > Build Settings and make sure that:

    1. O dispositivo de destino está definido como qualquer dispositivo.Target Device is set to Any Device.

      Para o Microsoft HoloLens, defina o dispositivo de destino para o hololens.For Microsoft HoloLens, set Target Device to HoloLens.

    2. O tipo de compilação está definido como D3DBuild Type is set to D3D

    3. O SDK está definido para o mais recente instaladoSDK is set to Latest installed

    4. A versão do Visual Studio está definida para o mais recente instaladoVisual Studio Version is set to Latest installed

    5. Compilar e executar é definido como computador localBuild and Run is set to Local Machine

    6. Salve a cena e adicione-a à compilação.Save the scene and add it to the build.

      1. Faça isso selecionando Adicionar abrir cenas.Do this by selecting Add Open Scenes. Uma janela salvar será exibida.A save window will appear.

        Adicionar cenas abertas

      2. Crie uma nova pasta para isso e qualquer cena futura, em seguida, selecione o botão nova pasta , para criar uma nova pasta, nomeie-a como cenas.Create a new folder for this, and any future, scene, then select the New folder button, to create a new folder, name it Scenes.

        criar pasta de cenas

      3. Abra sua pasta de cenas recém-criada e, no campo nome do arquivo: , digite FunctionsScenee pressione salvar.Open your newly created Scenes folder, and then in the File name: text field, type FunctionsScene, then press Save.

        cena de salvar funções

  6. As configurações restantes, em configurações de compilação, devem ser deixadas como padrão por enquanto.The remaining settings, in Build Settings, should be left as default for now.

    cena de salvar funções

  7. Na janela configurações de compilação , clique no botão configurações do Player , isso abrirá o painel relacionado no espaço onde o Inspetor está localizado.In the Build Settings window, click on the Player Settings button, this will open the related panel in the space where the Inspector is located.

    configurações do Player no Inspetor

  8. Nesse painel, algumas configurações precisam ser verificadas:In this panel, a few settings need to be verified:

    1. Na guia outras configurações :In the Other Settings tab:

      1. A versão de tempo de execução de script deve ser Experimental (.NET 4,6 equivalente), o que irá disparar uma necessidade de reiniciar o editor.Scripting Runtime Version should be Experimental (.NET 4.6 Equivalent), which will trigger a need to restart the Editor.
      2. O back-end de script deve ser .netScripting Backend should be .NET
      3. O nível de compatibilidade da API deve ser .NET 4,6API Compatibility Level should be .NET 4.6
    2. Na guia configurações de publicação , em recursos, marque:Within the Publishing Settings tab, under Capabilities, check:

      • InternetClientInternetClient

        definir recursos

    3. Mais adiante no painel, em configurações de XR (encontradas abaixo de configurações de publicação), suporte à realidade virtualem escala, verifique se o SDK do Windows Mixed Reality foi adicionado.Further down the panel, in XR Settings (found below Publishing Settings), tick Virtual Reality Supported, make sure the Windows Mixed Reality SDK is added.

      definir configurações de XR

  9. De volta às configurações de Build , os projetos do C# Unity não ficam mais esmaecidos; Marque a caixa de seleção ao lado deste.Back in Build Settings Unity C# Projects is no longer greyed out; tick the checkbox next to this.

    projetos em escala em c#

  10. Feche a janela configurações de compilação.Close the Build Settings window.

  11. Salve sua cena e projeto (arquivo > salvar cena/arquivo > salvar projeto).Save your Scene and Project (FILE > SAVE SCENE / FILE > SAVE PROJECT).

Capítulo 4-configurar a câmera principalChapter 4 - Setup Main Camera

Importante

Se você quiser ignorar os componentes de configuração do Unity deste curso e continuar diretamente no código, fique à vontade para baixar esse. unitypackagee importe-o para seu projeto como um pacote personalizado.If you wish to skip the Unity Set up components of this course, and continue straight into code, feel free to download this .unitypackage, and import it into your project as a Custom Package. Isso também conterá as DLLs do próximo capítulo.This will also contain the DLLs from the next Chapter. Após a importação, continue no capítulo 7.After import, continue from Chapter 7.

  1. No painel hierarquia, você encontrará um objeto chamado câmera principal, esse objeto representa o ponto de vista de "cabeçalho" quando você estiver "dentro" de seu aplicativo.In the Hierarchy Panel, you will find an object called Main Camera, this object represents your "head" point of view once you are "inside" your application.

  2. Com o painel do Unity na frente de você, selecione a câmera principal gameobject.With the Unity Dashboard in front of you, select the Main Camera GameObject. Você observará que o painel Inspetor (geralmente localizado à direita, dentro do painel) mostrará os vários componentes desse gameobject, com a transformação na parte superior, seguida pela câmerae alguns outros componentes.You will notice that the Inspector Panel (generally found to the right, within the Dashboard) will show the various components of that GameObject, with Transform at the top, followed by Camera, and some other components. Você precisará redefinir a transformação da câmera principal, para que ela seja posicionada corretamente.You will need to reset the Transform of the Main Camera, so it is positioned correctly.

  3. Para fazer isso, selecione o ícone de engrenagem ao lado do componente transformação da câmera e selecione Redefinir.To do this, select the Gear icon next to the Camera's Transform component, and select Reset.

    redefinir transformação

  4. Em seguida, atualize o componente transformar para se parecer com o seguinte:Then update the Transform component to look like:

    TRANSFORMAÇÃO-POSIÇÃOTRANSFORM - POSITION
    W.x.y.X IarY ZZ
    00 11 00
    TRANSFORMAÇÃO-ROTAÇÃOTRANSFORM - ROTATION
    W.x.y.X IarY ZZ
    00 00 00
    TRANSFORMAR EM ESCALATRANSFORM - SCALE
    W.x.y.X IarY ZZ
    11 11 11

    definir transformação de câmera

Capítulo 5-Configurando a cena do UnityChapter 5 - Setting up the Unity scene

  1. Clique com o botão direito do mouse em uma área vazia do painel hierarquia, em objeto 3D, adicione um plano.Right-click in an empty area of the Hierarchy Panel, under 3D Object, add a Plane.

    criar novo plano

  2. Com o objeto plano selecionado, altere os seguintes parâmetros no painel Inspetor:With the Plane object selected, change the following parameters in the Inspector Panel:

    TRANSFORMAÇÃO-POSIÇÃOTRANSFORM - POSITION
    W.x.y.X IarY ZZ
    00 00 44
    TRANSFORMAR EM ESCALATRANSFORM - SCALE
    W.x.y.X IarY ZZ
    1010 11 1010

    definir posição e escala do plano

    exibição da cena do plano

  3. Clique com o botão direito do mouse em uma área vazia do painel hierarquia, em objeto 3D, adicione um cubo.Right-click in an empty area of the Hierarchy Panel, under 3D Object, add a Cube.

    1. Renomeie o cubo para GazeButton (com o cubo selecionado, pressione ' F2 ').Rename the Cube to GazeButton (with the Cube selected, press 'F2').

    2. Altere os seguintes parâmetros no painel de Inspetor:Change the following parameters in the Inspector Panel:

      TRANSFORMAÇÃO-POSIÇÃOTRANSFORM - POSITION
      W.x.y.X IarY ZZ
      00 33 55

      definir transformação do botão olhar

      exibição de cena do botão olhar

    3. Clique no botão suspenso marca e clique em adicionar marca para abrir o painel marcas & camadas.Click on the Tag drop-down button and click on Add Tag to open the Tags & Layers Pane.

      Adicionar nova marca

      selecionar mais

    4. Selecione o botão + (mais) e, no campo nome da nova marca , digite GazeButtone pressione salvar.Select the + (plus) button, and in the New Tag Name field, enter GazeButton, and press Save.

      nomear nova marca

    5. Clique no objeto GazeButton no painel hierarquiae, no painel Inspetor, atribua a marca GazeButton recém-criada.Click on the GazeButton object in the Hierarchy Panel, and in the Inspector Panel, assign the newly created GazeButton tag.

      atribuir botão olhar à nova marca

  4. Clique com o botão direito do mouse no objeto GazeButton , no painel hierarquiae adicione um gameobject vazio (que será adicionado como um objeto filho ).Right-click on the GazeButton object, in the Hierarchy Panel, and add an Empty GameObject (which will be added as a child object).

  5. Selecione o novo objeto e renomeie-o ShapeSpawnPoint.Select the new object and rename it ShapeSpawnPoint.

    1. Altere os seguintes parâmetros no painel de Inspetor:Change the following parameters in the Inspector Panel:

      TRANSFORMAÇÃO-POSIÇÃOTRANSFORM - POSITION
      W.x.y.X IarY ZZ
      00 -1-1 00

      atualizar transformação de ponto de geração de forma

      exibição de cena de ponto de geração de forma

  6. Em seguida, você criará um objeto de texto 3D para fornecer comentários sobre o status do serviço do Azure.Next you will create a 3D Text object to provide feedback on the status of the Azure service.

    Clique com o botão direito do mouse em GazeButton no painel hierarquia novamente e adicione um objeto 3D > objeto de texto 3D como um filho.Right click on the GazeButton in the Hierarchy Panel again and add a 3D Object > 3D Text object as a child.

    criar novo objeto de texto 3D

  7. Renomeie o objeto de texto 3D para AzureStatusText.Rename the 3D Text object to AzureStatusText.

  8. Altere a transformação do objeto AzureStatusText da seguinte maneira:Change the AzureStatusText object Transform as follows:

    TRANSFORMAÇÃO-POSIÇÃOTRANSFORM - POSITION
    W.x.y.X IarY ZZ
    00 00 -0,6-0.6
    TRANSFORMAR EM ESCALATRANSFORM - SCALE
    W.x.y.X IarY ZZ
    0,10.1 0,10.1 0,10.1

    Observação

    Não se preocupe se parece estar fora do centro, pois isso será corrigido quando o componente de malha de texto abaixo for atualizado.Do not worry if it appears to be off-centre, as this will be fixed when the below Text Mesh component is updated.

  9. Altere o componente de malha de texto para corresponder ao seguinte:Change the Text Mesh component to match the below:

    definir componente de malha de texto

    Dica

    A cor selecionada aqui é a cor hexadecimal: 000000FF, embora sinta-se à vontade para escolher sua própria, apenas verifique se ela é legível.The selected color here is Hex color: 000000FF, though feel free to choose your own, just ensure it is readable.

  10. A estrutura do painel de hierarquia agora deve ser assim:Your Hierarchy Panel structure should now look like this:

    malha de texto na exibição de cena

  11. Sua cena agora deve se parecer com esta:Your scene should now look like this:

    malha de texto na exibição de cena

Capítulo 6 – importar o armazenamento do Azure para o UnityChapter 6 - Import Azure Storage for Unity

Você usará o armazenamento do Azure para Unity (que, por sua vez, utiliza o SDK do .net para o Azure).You will be using Azure Storage for Unity (which itself leverages the .Net SDK for Azure). Você pode ler mais sobre isso no artigo armazenamento do Azure para Unity.You can read more about this at the Azure Storage for Unity article.

Atualmente, há um problema conhecido no Unity que exige que os plugins sejam reconfigurados após a importação.There is currently a known issue in Unity which requires plugins to be reconfigured after import. Essas etapas (4-7 nesta seção) não serão mais necessárias depois que o bug for resolvido.These steps (4 - 7 in this section) will no longer be required after the bug has been resolved.

Para importar o SDK para seu próprio projeto, verifique se você baixou o '. unitypackage ' mais recente do GitHub.To import the SDK into your own project, make sure you have downloaded the latest '.unitypackage' from GitHub. Em seguida, faça o seguinte:Then, do the following:

  1. Adicione o arquivo . unitypackage ao Unity usando a opção de menu ativos > Importar pacote > pacote personalizado .Add the .unitypackage file to Unity by using the Assets > Import Package > Custom Package menu option.

  2. Na caixa Importar pacote do Unity que é exibida, você pode selecionar tudo em armazenamento > do plug-in .In the Import Unity Package box that pops up, you can select everything under Plugin > Storage. Desmarque todas as outras opções, pois elas não são necessárias para este curso.Uncheck everything else, as it is not needed for this course.

    importar para pacote

  3. Clique no botão importar para adicionar os itens ao seu projeto.Click the Import button to add the items to your project.

  4. Vá para a pasta de armazenamento em plug-ins, na exibição do projeto e selecione apenasos seguintes plugins:Go to the Storage folder under Plugins, in the Project view, and select the following plugins only:

    • Microsoft.Data.EdmMicrosoft.Data.Edm

    • Microsoft.Data.ODataMicrosoft.Data.OData

    • Microsoft. WindowsAzure. StorageMicrosoft.WindowsAzure.Storage

    • Newtonsoft.JsonNewtonsoft.Json

    • System.SpatialSystem.Spatial

      desmarcar qualquer plataforma

  5. Com esses plugins específicos selecionados, desmarque qualquer plataforma e desmarque WSAPlayer e clique em aplicar.With these specific plugins selected, uncheck Any Platform and uncheck WSAPlayer then click Apply.

    aplicar DLLs de plataforma

    Observação

    Estamos marcando esses plugins específicos para serem usados apenas no editor do Unity.We are marking these particular plugins to only be used in the Unity Editor. Isso ocorre porque há diferentes versões dos mesmos plug-ins na pasta WSA que serão usados depois que o projeto for exportado do Unity.This is because there are different versions of the same plugins in the WSA folder that will be used after the project is exported from Unity.

  6. Na pasta plug-in de armazenamento , selecione somente:In the Storage plugin folder, select only:

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

      definir não processar para DLLs

  7. Marque a caixa não processar em configurações da plataforma e clique em aplicar.Check the Don't Process box under Platform Settings and click Apply.

    aplicar nenhum processamento

    Observação

    Estamos marcando este plug-in "não processar" porque o assembly do Unity Patcher tem dificuldade para processar esse plug-in.We are marking this plugin "Don't process" because the Unity assembly patcher has difficulty processing this plugin. O plug-in ainda funcionará, embora não seja processado.The plugin will still work even though it is not processed.

Capítulo 7-criar a classe AzureservicesChapter 7 - Create the AzureServices class

A primeira classe que você pretende criar é a classe azureservices .The first class you are going to create is the AzureServices class.

A classe azureservices será responsável por:The AzureServices class will be responsible for:

  • Armazenando as credenciais da conta do Azure.Storing Azure Account credentials.

  • Chamando sua função Azure App.Calling your Azure App Function.

  • O upload e o download do arquivo de dados no armazenamento em nuvem do Azure.The upload and download of the data file in your Azure Cloud Storage.

Para criar esta classe:To create this Class:

  1. Clique com o botão direito do mouse na pasta ativo , localizada no painel projeto, crie > pasta.Right-click in the Asset Folder, located in the Project Panel, Create > Folder. Nomeie a pasta scripts.Name the folder Scripts.

    criar nova pasta

    pasta de chamadas-scripts

  2. Clique duas vezes na pasta recém-criada para abri-la.Double click on the folder just created, to open it.

  3. Clique com o botão direito do mouse dentro da pasta, crie > C# script.Right-click inside the folder, Create > C# Script. Chame o script azureservices.Call the script AzureServices.

  4. Clique duas vezes na nova classe azureservices para abri-la com o Visual Studio.Double click on the new AzureServices class to open it with Visual Studio.

  5. Adicione os seguintes namespaces à parte superior do azureservices:Add the following namespaces to the top of the AzureServices:

        using System;
        using System.Threading.Tasks;
        using UnityEngine;
        using Microsoft.WindowsAzure.Storage;
        using Microsoft.WindowsAzure.Storage.File;
        using System.IO;
        using System.Net;
    
  6. Adicione os seguintes campos de Inspetor dentro da classe azureservices :Add the following Inspector Fields inside the AzureServices class:

        /// <summary>
        /// Provides Singleton-like behavior to this class.
        /// </summary>
        public static AzureServices instance;
    
        /// <summary>
        /// Reference Target for AzureStatusText Text Mesh object
        /// </summary>
        public TextMesh azureStatusText;
    
  7. Em seguida, adicione as seguintes variáveis de membro dentro da classe azureservices :Then add the following member variables inside the AzureServices class:

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

    Importante

    Substitua os valores do ponto de extremidade e da cadeia de conexão pelos valores do seu armazenamento do Azure, encontrado no portal do AzureMake sure you replace the endpoint and connection string values with the values from your Azure storage, found in the Azure Portal

  8. O código para os métodos ativo () e Iniciar () agora precisa ser adicionado.Code for Awake() and Start() methods now needs to be added. Esses métodos serão chamados quando a classe inicializar:These methods will be called when the class initializes:

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

    Importante

    Iremos preencher o código para CallAzureFunctionForNextShape () em um capítulo futuro.We will fill in the code for CallAzureFunctionForNextShape() in a future Chapter.

  9. Exclua o método Update () , pois essa classe não o usará.Delete the Update() method since this class will not use it.

  10. Salve suas alterações no Visual Studio e, em seguida, retorne ao Unity.Save your changes in Visual Studio, and then return to Unity.

  11. Clique e arraste a classe azureservices da pasta scripts para o objeto de câmera principal no painel hierarquia.Click and drag the AzureServices class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

  12. Selecione a câmera principal e, em seguida, pegue o objeto filho AzureStatusText sob o objeto GazeButton e coloque-o dentro do campo destino de referência do AzureStatusText , no Inspetor, para fornecer a referência ao script do azureservices .Select the Main Camera, then grab the AzureStatusText child object from beneath the GazeButton object, and place it within the AzureStatusText reference target field, in the Inspector, to provide the reference to the AzureServices script.

    atribuir destino de referência de texto de status do Azure

Capítulo 8-criar a classe ShapeFactoryChapter 8 - Create the ShapeFactory class

O próximo script a ser criado é a classe ShapeFactory .The next script to create, is the ShapeFactory class. A função dessa classe é criar uma nova forma, quando solicitado, e manter um histórico das formas criadas em uma lista de histórico de formas.The role of this class is to create a new shape, when requested, and keep a history of the shapes created in a Shape History List. Sempre que uma forma é criada, a lista de histórico de formas é atualizada na classe AzureService e, em seguida, armazenada no armazenamento do Azure.Every time a shape is created, the Shape History list is updated in the AzureService class, and then stored in your Azure Storage. Quando o aplicativo for iniciado, se um arquivo armazenado for encontrado no armazenamento do Azure, a lista do histórico de formas será recuperada e reproduzida, com o objeto de texto 3D que fornecerá se a forma gerada é do armazenamento ou de nova.When the application starts, if a stored file is found in your Azure Storage, the Shape History list is retrieved and replayed, with the 3D Text object providing whether the generated shape is from storage, or new.

Para criar esta classe:To create this class:

  1. Vá para a pasta scripts que você criou anteriormente.Go to the Scripts folder you created previously.

  2. Clique com o botão direito do mouse dentro da pasta, crie > C# script.Right-click inside the folder, Create > C# Script. Chame o script ShapeFactory.Call the script ShapeFactory.

  3. Clique duas vezes no novo script ShapeFactory para abri-lo com o Visual Studio.Double click on the new ShapeFactory script to open it with Visual Studio.

  4. Verifique se a classe ShapeFactory inclui os seguintes namespaces:Ensure the ShapeFactory class includes the following namespaces:

        using System.Collections.Generic;
        using UnityEngine;
    
  5. Adicione as variáveis mostradas abaixo à classe ShapeFactory e substitua as funções Start () e ativo () pelas seguintes:Add the variables shown below to the ShapeFactory class, and replace the Start() and Awake() functions with those below:

        /// <summary>
        /// Provide this class Singleton-like behaviour
        /// </summary>
        [HideInInspector]
        public static ShapeFactory instance;
    
        /// <summary>
        /// Provides an Inspector exposed reference to ShapeSpawnPoint
        /// </summary>
        [SerializeField]
        public Transform spawnPoint;
    
        /// <summary>
        /// Shape History Index
        /// </summary>
        [HideInInspector]
        public List<int> shapeHistoryList;
    
        /// <summary>
        /// Shapes Enum for selecting required shape
        /// </summary>
        private enum Shapes { Cube, Sphere, Cylinder }
    
        private void Awake()
        {
            instance = this;
        }
    
        private void Start()
        {
            shapeHistoryList = new List<int>();
        }
    
  6. O método createShape () gera as formas primitivas, com base no parâmetro inteiro fornecido.The CreateShape() method generates the primitive shapes, based upon the provided integer parameter. O parâmetro booliano é usado para especificar se a forma criada no momento é do armazenamento ou de nova.The Boolean parameter is used to specify whether the currently created shape is from storage, or new. Coloque o seguinte código em sua classe ShapeFactory , abaixo dos métodos anteriores:Place the following code in your ShapeFactory class, below the previous methods:

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

  8. De volta ao editor do Unity, clique e arraste a classe ShapeFactory da pasta scripts para o objeto da câmera principal no painel hierarquia.Back in the Unity Editor, click and drag the ShapeFactory class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

  9. Com a câmera principal selecionada, você observará que o componente de script ShapeFactory não tem a referência de ponto de geração .With the Main Camera selected you will notice the ShapeFactory script component is missing the Spawn Point reference. Para corrigi-lo, arraste o objeto ShapeSpawnPoint do painel hierarquia para o destino de referência do ponto de geração .To fix it, drag the ShapeSpawnPoint object from the Hierarchy Panel to the Spawn Point reference target.

    definir destino de referência de fábrica de forma

Capítulo 9-criar a classe olharChapter 9 - Create the Gaze class

O último script que você precisa criar é a classe olhar .The last script you need to create is the Gaze class.

Essa classe é responsável por criar um Raycast que será projetado para a frente da câmera principal, para detectar qual objeto o usuário está olhando.This class is responsible for creating a Raycast that will be projected forward from the Main Camera, to detect which object the user is looking at. Nesse caso, o Raycast precisará identificar se o usuário está olhando para o objeto GazeButton na cena e disparar um comportamento.In this case, the Raycast will need to identify if the user is looking at the GazeButton object in the scene and trigger a behavior.

Para criar esta classe:To create this Class:

  1. Vá para a pasta scripts que você criou anteriormente.Go to the Scripts folder you created previously.

  2. Clique com o botão direito do mouse no painel projeto, crie > C# script.Right-click in the Project Panel, Create > C# Script. Chame o script olhar.Call the script Gaze.

  3. Clique duas vezes no novo script olhar para abri-lo com o Visual Studio.Double click on the new Gaze script to open it with Visual Studio.

  4. Verifique se o namespace a seguir está incluído na parte superior do script:Ensure the following namespace is included at the top of the script:

        using UnityEngine;
    
  5. Em seguida, adicione as seguintes variáveis dentro da classe olhar :Then add the following variables inside the Gaze class:

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

Importante

Algumas dessas variáveis poderão ser editadas no Editor.Some of these variables will be able to be edited in the Editor.

  1. Agora, o código para os métodos ativo () e Iniciar () precisa ser adicionado.Code for the Awake() and Start() methods now needs to be added.

        /// <summary>
        /// The method used after initialization of the scene, though before Start().
        /// </summary>
        private void Awake()
        {
            // Set this class to behave similar to singleton
            instance = this;
        }
    
        /// <summary>
        /// Start method used upon initialization.
        /// </summary>
        private void Start()
        {
            FocusedObject = null;
            Cursor = CreateCursor();
        }
    
  2. Adicione o código a seguir, que criará um objeto cursor no início, juntamente com o método Update () , que executará o método Raycast, juntamente com o local em que o booliano GazeEnabled é alternado:Add the following code, which will create a cursor object at start, along with the Update() method, which will run the Raycast method, along with being where the GazeEnabled boolean is toggled:

        /// <summary>
        /// Method to create a cursor object.
        /// </summary>
        /// <returns></returns>
        private GameObject CreateCursor()
        {
            GameObject newCursor = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            newCursor.SetActive(false);
    
            // Remove the collider, so it doesn't block raycast.
            Destroy(newCursor.GetComponent<SphereCollider>());
            newCursor.transform.localScale = CursorSize;
    
            newCursor.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Diffuse"))
            {
                color = CursorColour
            };
    
            newCursor.name = "Cursor";
    
            newCursor.SetActive(true);
    
            return newCursor;
        }
    
        /// <summary>
        /// Called every frame
        /// </summary>
        private void Update()
        {
            if(GazeEnabled == true)
            {
                _gazeOrigin = Camera.main.transform.position;
    
                _gazeDirection = Camera.main.transform.forward;
    
                UpdateRaycast();
            }
        }
    
  3. Em seguida, adicione o método UpdateRaycast () , que projetará um Raycast e detectará o destino de acesso.Next add the UpdateRaycast() method, which will project a Raycast and detect the hit target.

        private void UpdateRaycast()
        {
            // Set the old focused gameobject.
            _oldFocusedObject = FocusedObject;
    
            RaycastHit hitInfo;
    
            // Initialise Raycasting.
            Hit = Physics.Raycast(_gazeOrigin,
                _gazeDirection,
                out hitInfo,
                GazeMaxDistance, LayerMask);
    
            HitInfo = hitInfo;
    
            // Check whether raycast has hit.
            if (Hit == true)
            {
                Position = hitInfo.point;
    
                Normal = hitInfo.normal;
    
                // Check whether the hit has a collider.
                if (hitInfo.collider != null)
                {
                    // Set the focused object with what the user just looked at.
                    FocusedObject = hitInfo.collider.gameObject;
                }
                else
                {
                    // Object looked on is not valid, set focused gameobject to null.
                    FocusedObject = null;
                }
            }
            else
            {
                // No object looked upon, set focused gameobject to null.
                FocusedObject = null;
    
                // Provide default position for cursor.
                Position = _gazeOrigin + (_gazeDirection * GazeMaxDistance);
    
                // Provide a default normal.
                Normal = _gazeDirection;
            }
    
            // Lerp the cursor to the given position, which helps to stabilize the gaze.
            Cursor.transform.position = Vector3.Lerp(Cursor.transform.position, Position, 0.6f);
    
            // Check whether the previous focused object is this same 
            //    object. If so, reset the focused object.
            if (FocusedObject != _oldFocusedObject)
            {
                ResetFocusedObject();
    
                if (FocusedObject != null)
                {
                if (FocusedObject.CompareTag(InteractibleTag.ToString()))
                {
                        // Set the Focused object to green - success!
                        FocusedObject.GetComponent<Renderer>().material.color = Color.green;
    
                        // Start the Azure Function, to provide the next shape!
                        AzureServices.instance.CallAzureFunctionForNextShape();
                    }
                }
            }
        }
    
  4. Por fim, adicione o método ResetFocusedObject () , que irá alternar a cor atual dos objetos GazeButton, indicando se ele está criando uma nova forma ou não.Lastly, add the ResetFocusedObject() method, which will toggle the GazeButton objects current color, indicating whether it is creating a new shape or not.

        /// <summary>
        /// Reset the old focused object, stop the gaze timer, and send data if it
        /// is greater than one.
        /// </summary>
        private void ResetFocusedObject()
        {
            // Ensure the old focused object is not null.
            if (_oldFocusedObject != null)
            {
                if (_oldFocusedObject.CompareTag(InteractibleTag.ToString()))
                {
                    // Set the old focused object to red - its original state.
                    _oldFocusedObject.GetComponent<Renderer>().material.color = Color.red;
                }
            }
        }
    
  5. Salve suas alterações no Visual Studio antes de retornar ao Unity.Save your changes in Visual Studio before returning to Unity.

  6. Clique e arraste a classe olhar da pasta scripts para o objeto de câmera principal no painel hierarquia.Click and drag the Gaze class from the Scripts folder to the Main Camera object in the Hierarchy Panel.

Capítulo 10 – concluindo a classe AzureservicesChapter 10 - Completing the AzureServices class

Com os outros scripts em vigor, agora é possível concluir a classe azureservices .With the other scripts in place, it is now possible to complete the AzureServices class. Isso será obtido por meio de:This will be achieved through:

  1. Adicionar um novo método chamado CreateCloudIdentityAsync () para configurar as variáveis de autenticação necessárias para se comunicar com o Azure.Adding a new method named CreateCloudIdentityAsync(), to set up the authentication variables needed for communicating with Azure.

    Esse método também verificará a existência de um arquivo armazenado anteriormente que contém a lista de formas.This method will also check for the existence of a previously stored File containing the Shape List.

    Se o arquivo for encontrado, ele desabilitará o usuário olhare disparará a criação de forma, de acordo com o padrão de formas, conforme armazenado no arquivo de armazenamento do Azure.If the file is found, it will disable the user Gaze, and trigger Shape creation, according to the pattern of shapes, as stored in the Azure Storage file. O usuário pode ver isso, pois a malha de texto fornecerá exibir ' armazenamento ' ou ' novo ', dependendo da origem das formas.The user can see this, as the Text Mesh will provide display 'Storage' or 'New', depending on the shapes origin.

    Se nenhum arquivo for encontrado, ele permitirá o olhar, permitindo que o usuário crie formas ao examinar o objeto GazeButton na cena.If no file is found, it will enable the Gaze, enabling the user to create shapes when looking at the GazeButton object in the scene.

        /// <summary>
        /// Create the references necessary to log into Azure
        /// </summary>
        private async void CreateCloudIdentityAsync()
        {
            // Retrieve storage account information from connection string
            storageAccount = CloudStorageAccount.Parse(storageConnectionString);
    
            // Create a file client for interacting with the file service.
            fileClient = storageAccount.CreateCloudFileClient();
    
            // Create a share for organizing files and directories within the storage account.
            share = fileClient.GetShareReference(fileShare);
    
            await share.CreateIfNotExistsAsync();
    
            // Get a reference to the root directory of the share.
            CloudFileDirectory root = share.GetRootDirectoryReference();
    
            // Create a directory under the root directory
            dir = root.GetDirectoryReference(storageDirectory);
    
            await dir.CreateIfNotExistsAsync();
    
            //Check if the there is a stored text file containing the list
            shapeIndexCloudFile = dir.GetFileReference("TextShapeFile");
    
            if (!await shapeIndexCloudFile.ExistsAsync())
            {
                // File not found, enable gaze for shapes creation
                Gaze.instance.GazeEnabled = true;
    
                azureStatusText.text = "No Shape\nFile!";
            }
            else
            {
                // The file has been found, disable gaze and get the list from the file
                Gaze.instance.GazeEnabled = false;
    
                azureStatusText.text = "Shape File\nFound!";
    
                await ReplicateListFromAzureAsync();
            }
        }
    
  2. O próximo trecho de código é de dentro do método Start () ; Onde será feita uma chamada para o método CreateCloudIdentityAsync () .The next code snippet is from within the Start() method; wherein a call will be made to the CreateCloudIdentityAsync() method. Fique à vontade para copiar sobre o método Start () atual, com o seguinte:Feel free to copy over your current Start() method, with the below:

        private void Start()
        {
            // Disable TLS cert checks only while in Unity Editor (until Unity adds support for TLS)
    #if UNITY_EDITOR
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    #endif
    
            // Set the Status text to loading, whilst attempting connection to Azure.
            azureStatusText.text = "Loading...";
    
            //Creating the references necessary to log into Azure and check if the Storage Directory is empty
            CreateCloudIdentityAsync();
        }
    
  3. Preencha o código para o método CallAzureFunctionForNextShape () .Fill in the code for the method CallAzureFunctionForNextShape(). Você usará o Azure aplicativo de funções criado anteriormente para solicitar um índice de forma.You will use the previously created Azure Function App to request a shape index. Depois que a nova forma for recebida, esse método enviará a forma para a classe ShapeFactory para criar a nova forma na cena.Once the new shape is received, this method will send the shape to the ShapeFactory class to create the new shape in the scene. Use o código abaixo para concluir o corpo de CallAzureFunctionForNextShape () .Use the code below to complete the body of CallAzureFunctionForNextShape().

        /// <summary>
        /// Call to the Azure Function App to request a Shape.
        /// </summary>
        public async void CallAzureFunctionForNextShape()
        {
            int azureRandomInt = 0;
    
            // Call Azure function
            HttpWebRequest webRequest = WebRequest.CreateHttp(azureFunctionEndpoint);
    
            WebResponse response = await webRequest.GetResponseAsync();
    
            // Read response as string
            using (Stream stream = response.GetResponseStream())
            {
                StreamReader reader = new StreamReader(stream);
    
                String responseString = reader.ReadToEnd();
    
                //parse result as integer
                Int32.TryParse(responseString, out azureRandomInt);
            }
    
            //add random int from Azure to the ShapeIndexList
            ShapeFactory.instance.shapeHistoryList.Add(azureRandomInt);
    
            ShapeFactory.instance.CreateShape(azureRandomInt, false);
    
            //Save to Azure storage
            await UploadListToAzureAsync();
        }
    
  4. Adicione um método para criar uma cadeia de caracteres, concatenando os inteiros armazenados na lista de histórico de formas e salvando-os em seu arquivo de armazenamento do Azure.Add a method to create a string, by concatenating the integers stored in the shape history list, and saving it in your Azure Storage File.

        /// <summary>
        /// Upload the locally stored List to Azure
        /// </summary>
        private async Task UploadListToAzureAsync()
        {
            // Uploading a local file to the directory created above
            string listToString = string.Join(",", ShapeFactory.instance.shapeHistoryList.ToArray());
    
            await shapeIndexCloudFile.UploadTextAsync(listToString);
        }
    
  5. Adicione um método para recuperar o texto armazenado no arquivo localizado no arquivo de armazenamento do Azure e desserializá -lo em uma lista.Add a method to retrieve the text stored in the file located in your Azure Storage File and deserialize it into a list.

  6. Quando esse processo for concluído, o método reabilitará o olhar para que o usuário possa adicionar mais formas à cena.Once this process is completed, the method re-enables the gaze so that the user can add more shapes to the scene.

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

Capítulo 11-criar a solução UWPChapter 11 - Build the UWP Solution

Para iniciar o processo de compilação:To begin the Build process:

  1. Vá para arquivo > configurações de Build.Go to File > Build Settings.

    compilar o aplicativo

  2. Clique em Compilar.Click Build. O Unity iniciará uma janela Explorador de arquivos , onde você precisará criar e, em seguida, selecionar uma pasta na qual o aplicativo será compilado.Unity will launch a File Explorer window, where you need to create and then select a folder to build the app into. Crie essa pasta agora e nomeie-a como aplicativo.Create that folder now, and name it App. Em seguida, com a pasta de aplicativo selecionada, pressione Selecionar pasta.Then with the App folder selected, press Select Folder.

  3. O Unity começará a criar seu projeto na pasta do aplicativo .Unity will begin building your project to the App folder.

  4. Depois que o Unity terminar a compilação (pode levar algum tempo), ele abrirá uma janela do Explorador de arquivos no local de sua compilação (verifique sua barra de tarefas, pois ela nem sempre aparecerá acima das janelas, mas o notificará sobre a adição de uma nova janela).Once Unity has finished building (it might take some time), it will open a File Explorer window at the location of your build (check your task bar, as it may not always appear above your windows, but will notify you of the addition of a new window).

Capítulo 12-implantando seu aplicativoChapter 12 - Deploying your application

Para implantar seu aplicativo:To deploy your application:

  1. Navegue até a pasta do aplicativo que foi criada no último capítulo.Navigate to the App folder which was created in the last Chapter. Você verá um arquivo com o nome de seus aplicativos, com a extensão '. sln ', que você deve clicar duas vezes para abri-lo no Visual Studio.You will see a file with your apps name, with the '.sln' extension, which you should double-click, so to open it within Visual Studio.

  2. Na plataforma da solução, selecione x86, computador local.In the Solution Platform, select x86, Local Machine.

  3. Na configuração da solução , selecione depurar.In the Solution Configuration select Debug.

    Para o Microsoft HoloLens, você pode achar mais fácil definir isso como computador remoto, para que você não esteja vinculado ao seu computador.For the Microsoft HoloLens, you may find it easier to set this to Remote Machine, so that you are not tethered to your computer. No entanto, também será necessário fazer o seguinte:Though, you will need to also do the following:

    • Conheça o endereço IP do seu HoloLens, que pode ser encontrado dentro das configurações > rede & Internet > Wi-Fi > Opções avançadas; o IPv4 é o endereço que você deve usar.Know the IP Address of your HoloLens, which can be found within the Settings > Network & Internet > Wi-Fi > Advanced Options; the IPv4 is the address you should use.
    • Verificar se o modo de desenvolvedor está ativado; encontrado em configurações > atualização & > de segurança para desenvolvedores.Ensure Developer Mode is On; found in Settings > Update & Security > For developers.

    implantar solução

  4. Vá para o menu Compilar e clique em implantar solução para Sideload o aplicativo em seu computador.Go to the Build menu and click on Deploy Solution to sideload the application to your machine.

  5. Seu aplicativo agora deve aparecer na lista de aplicativos instalados, pronto para ser iniciado e testado!Your App should now appear in the list of installed apps, ready to be launched and tested!

O Azure Functions e o aplicativo de armazenamento concluídosYour finished Azure Functions and Storage Application

Parabéns, você criou um aplicativo de realidade misturada que aproveita tanto o Azure Functions quanto os serviços de armazenamento do Azure.Congratulations, you built a mixed reality app that leverages both the Azure Functions and Azure Storage services. Seu aplicativo poderá desenhar dados armazenados e fornecer uma ação com base nesses dados.Your app will be able to draw on stored data, and provide an action based on that data.

final do produto final

Exercícios de bônusBonus exercises

Exercício 1Exercise 1

Crie um segundo ponto de geração e registro do qual ponto de geração um objeto foi criado.Create a second spawn point and record which spawn point an object was created from. Ao carregar o arquivo de dados, reproduza as formas que estão sendo geradas do local em que foram criadas originalmente.When you load the data file, replay the shapes being spawned from the location they originally were created.

Exercício 2Exercise 2

Crie uma maneira de reiniciar o aplicativo, em vez de ter que reabri-lo a cada vez.Create a way to restart the app, rather than having to re-open it each time. O carregamento de cenas é um bom ponto de partida.Loading Scenes is a good spot to start. Depois de fazer isso, crie uma maneira de limpar a lista armazenada no armazenamento do Azure, para que ela possa ser redefinida facilmente do seu aplicativo.After doing that, create a way to clear the stored list in Azure Storage, so that it can be easily reset from your app.