MR e Azure 309: Application InsightsMR and Azure 309: Application insights


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.


início do produto final

Neste curso, você aprenderá a adicionar recursos de Application Insights a um aplicativo de realidade misturada, usando a API do Aplicativo Azure insights para coletar análises sobre o comportamento do usuário.In this course, you will learn how to add Application Insights capabilities to a mixed reality application, using the Azure Application Insights API to collect analytics regarding user behavior.

Application Insights é um serviço da Microsoft, permitindo aos desenvolvedores coletar análises de seus aplicativos e gerenciá-los de um portal fácil de usar.Application Insights is a Microsoft service, allowing developers to collect analytics from their applications and manage it from an easy-to-use portal. A análise pode ser qualquer coisa, desde o desempenho até as informações personalizadas que você gostaria de coletar.The analytics can be anything from performance to custom information you would like to collect. Para obter mais informações, visite a página Application insights.For more information, visit the Application Insights page.

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 e mova-se em uma cena.Allow the user to gaze and move around a scene.
  2. Dispare o envio de análises para o serviço de Application insights, por meio do uso de olhar e proximidade para objetos em cena.Trigger the sending of analytics to the Application Insights Service, through the use of Gaze and Proximity to in-scene objects.
  3. O aplicativo também chamará o serviço, buscando informações sobre qual objeto foi mais abordado pelo usuário, nas últimas 24 horas.The app will also call upon the Service, fetching information about which object has been approached the most by the user, within the last 24 hours. Esse objeto alterará sua cor para verde.That object will change its color to green.

Este curso ensinará a você como obter os resultados do serviço de Application Insights em um aplicativo de exemplo baseado em Unity.This course will teach you how to get the results from the Application Insights Service, into a Unity-based sample application. Será necessário aplicar esses conceitos a um aplicativo personalizado que você possa estar criando.It will be up to you to apply these concepts to a custom application you might be building.

Suporte a dispositivosDevice support

CursoCourse HoloLensHoloLens Headsets imersivosImmersive headsets
MR e Azure 309: Application InsightsMR and Azure 309: Application insights ✔️✔️ ✔️✔️

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. Ao usar o HoloLens, você pode notar um eco durante a captura de voz.When using HoloLens, you may notice some echo during voice capture.

Pré-requisitosPrerequisites

Observação

Este tutorial foi projetado para desenvolvedores que têm experiência básica com o Unity e o C#.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 (julho 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 (July 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 correspondam perfeitamente ao que você encontrará no software mais recente do que o que está listado 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 will find in newer software than what is 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).

Aviso

Lembre-se de que os dados enviados para Application insights leva tempo, portanto, seja paciente.Be aware, data going to Application Insights takes time, so be patient. Se você quiser verificar se o serviço recebeu seus dados, confira o capítulo 14, que lhe mostrará como navegar no Portal.If you want to check if the Service has received your data, check out Chapter 14, which will show you how to navigate the portal.

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

Para usar Application insights, será necessário criar e configurar um serviço de Application insights no portal do Azure.To use Application Insights, you will need to create and configure an Application Insights Service 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 Application insights e clique em Enter.Once you are logged in, click on New in the top left corner, and search for Application Insights, and click Enter.

    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.

    Portal do Azure

  3. A nova página à direita fornecerá uma descrição do serviço de informações de aplicativo Azure .The new page to the right will provide a description of the Azure Application Insights Service. Na parte inferior esquerda desta página, selecione o botão criar para criar uma associação com esse serviço.At the bottom left of this page, select the Create button, to create an association with this Service.

    Portal do Azure

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

    1. Insira o nome desejado para esta instância de serviço.Insert your desired Name for this Service instance.

    2. Como tipo de aplicativo, selecione geral.As Application Type, select General.

    3. Selecione uma assinatura apropriada.Select an appropriate Subscription.

    4. 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 cursos) 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 courses) 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.

    5. Selecione um Local.Select a Location.

    6. 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.

    7. Selecione Criar.Select Create.

      Portal do Azure

  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.

    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.

    Portal do Azure

  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 Application insights .You will be taken to your new Application Insights Service instance.

    Portal do Azure

    Observação

    Mantenha essa página da Web aberta e fácil de acessar, você voltará aqui para ver os dados coletados.Keep this web page open and easy to access, you will come back here often to see the data collected.

    Importante

    Para implementar Application Insights, será necessário usar três (3) valores específicos: chave de Instrumentação, ID do aplicativo e chave de API.To implement Application Insights, you will need to use three (3) specific values: Instrumentation Key, Application ID, and API Key. Abaixo, você verá como recuperar esses valores do seu serviço.Below you will see how to retrieve these values from your Service. Lembre-se de anotar esses valores em uma página de bloco de notas em branco, pois você os usará em breve em seu código.Make sure to note these values on a blank Notepad page, because you will use them soon in your code.

  9. Para localizar a chave de instrumentação, você precisará rolar a lista de funções de serviço e clicar em Propriedades, a guia exibida revelará a chave de serviço.To find the Instrumentation Key, you will need to scroll down the list of Service functions, and click on Properties, the tab displayed will reveal the Service Key.

    Portal do Azure

  10. Um pouco abaixo das propriedades, você encontrará o acesso à API, no qual você precisa clicar.A little below Properties, you will find API Access, which you need to click. O painel à direita fornecerá a ID do aplicativo do seu aplicativo.The panel to the right will provide the Application ID of your app.

    Portal do Azure

  11. Com o painel ID do aplicativo ainda aberto, clique em criar chave de API, que abrirá o painel criar chave de API .With the Application ID panel still open, click Create API Key, which will open the Create API key panel.

    Portal do Azure

  12. No painel abrir a chave de API criar agora, digite uma descrição e marque as três caixas.Within the now open Create API key panel, type a description, and tick the three boxes.

  13. Clique em gerar chave.Click Generate Key. Sua chave de API será criada e exibida.Your API Key will be created and displayed.

    Portal do Azure

    Aviso

    Essa é a única vez que a sua chave de serviço será exibida, portanto, certifique-se de fazer uma cópia dela agora.This is the only time your Service Key will be displayed, so ensure you make a copy of it now.

Capítulo 2 – configurar o projeto do UnityChapter 2 - Set up the Unity project

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

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

    Configurar o projeto do Unity

  2. Agora, você precisará fornecer um nome de projeto do Unity, inserir o Sr _ _ Application _ insights do Azure.You will now need to provide a Unity Project name, insert MR_Azure_Application_Insights. Verifique se o modelo está definido como 3D.Make sure the Template 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.

    Configurar o 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 e, em seguida, na janela novo, 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.

    Configurar o projeto do Unity

  4. Em seguida, vá para arquivo > configurações de compilação e alterne a plataforma para plataforma universal do Windows, clicando 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.

    Configurar o projeto do Unity

  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 para qualquer dispositivoTarget Device is set to Any device

      Para o Microsoft HoloLens, defina o dispositivo de destino como HoloLens.For the 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. Compilar e executar é definido como computador localBuild and Run is set to Local Machine

    5. 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.

        Configurar o projeto do Unity

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

        Configurar o projeto do Unity

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

        Configurar o projeto do Unity

  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.

  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.

    Configurar o projeto do Unity

  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

      Configurar o projeto do Unity

    2. Na guia configurações de publicação , em recursos, marque:Within the Publishing Settings tab, under Capabilities, check:

      • InternetClientInternetClient

        Configurar o projeto do Unity

    3. Mais adiante no painel, em configurações de XR (encontradas abaixo de configurações de publicação), suporte à realidade virtual em 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.

      Configurar o projeto do Unity

  9. De volta às configurações de Build, os projetos do Unity C# 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.

  10. Feche a janela Configurações de Build.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 3 – importar o pacote do UnityChapter 3 - Import the Unity package

Importante

Se você quiser ignorar os componentes de configuração do Unity deste curso e continuar diretamente no código, fique à vontade para baixar este Azure-Mr-309. unitypackage, 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 Azure-MR-309.unitypackage, 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 6.After import, continue from Chapter 6.

Importante

Para usar Application Insights no Unity, você precisa importar a DLL para ela, juntamente com a DLL Newtonsoft.To use Application Insights within Unity, you need to import the DLL for it, along with the Newtonsoft DLL. 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 Application Insights para seu próprio projeto, verifique se você baixou o '. unitypackage ', que contém os plug-ins.To import Application Insights into your own project, make sure you have downloaded the '.unitypackage', containing the plugins. Em seguida, faça o seguinte:Then, do the following:

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

  2. Na caixa Importar pacote de Unity que é exibida, verifique se tudo em (e incluindo) plug-ins está selecionado.In the Import Unity Package box that pops up, ensure everything under (and including) Plugins is selected.

    Importar o pacote do Unity

  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 insights em plug-ins na exibição do projeto e selecione os seguintes plugins somente:Go to the Insights folder under Plugins in the Project view and select the following plugins only:

    • Microsoft.ApplicationInsightsMicrosoft.ApplicationInsights

    Importar o pacote do Unity

  5. Com este plug-in selecionado, verifique se qualquer plataforma está desmarcada e, em seguida, verifique se WSAPlayer também está desmarcado e clique em aplicar.With this plugin selected, ensure that Any Platform is unchecked, then ensure that WSAPlayer is also unchecked, then click Apply. Fazer isso é apenas para confirmar que os arquivos estão configurados corretamente.Doing this is just to confirm that the files are configured correctly.

    Importar o pacote do Unity

    Observação

    Marcando os plug-ins como este, os configura para serem usados apenas no editor do Unity.Marking the plugins like this, configures them to only be used in the Unity Editor. Há um conjunto diferente de DLLs na pasta WSA que será usado depois que o projeto for exportado do Unity.There are a different set of DLLs in the WSA folder which will be used after the project is exported from Unity.

  6. Em seguida, você precisa abrir a pasta WSA na pasta insights .Next, you need to open the WSA folder, within the Insights folder. Você verá uma cópia do mesmo arquivo que acabou de configurar.You will see a copy of the same file you just configured. Selecione esse arquivo e, no Inspetor, verifique se qualquer plataforma está desmarcada e, em seguida, verifique se somente WSAPlayer está marcado.Select this file, and then in the inspector, ensure that Any Platform is unchecked, then ensure that only WSAPlayer is checked. Clique em Aplicar.Click Apply.

    Importar o pacote do Unity

  7. Agora, você precisará seguir as etapas de 4-6, mas para os plug-ins Newtonsoft em vez disso.You will now need to follow steps 4-6, but for the Newtonsoft plugins instead. Consulte a captura de tela abaixo para saber a aparência do resultado.See the below screenshot for what the outcome should look like.

    Importar o pacote do Unity

Capítulo 4-configurar os controles de câmera e de usuárioChapter 4 - Set up the camera and user controls

Neste capítulo, você configurará a câmera e os controles para permitir que o usuário veja e mova-se na cena.In this Chapter you will set up the camera and the controls to allow the user to see and move in the scene.

  1. Clique com o botão direito do mouse em uma área vazia no painel hierarquia e, em seguida, em criar > vazio.Right-click in an empty area in the Hierarchy Panel, then on Create > Empty.

    Configurar a câmera e os controles de usuário

  2. Renomeie o novo gameobject vazio para a câmera pai.Rename the new empty GameObject to Camera Parent.

    Configurar a câmera e os controles de usuário

  3. Clique com o botão direito do mouse em uma área vazia no painel hierarquia, depois em objeto 3D e, em seguida, em esfera.Right-click in an empty area in the Hierarchy Panel, then on 3D Object, then on Sphere.

  4. Renomeie a esfera para a direita.Rename the Sphere to Right Hand.

  5. Defina a escala de transformação da mão direita para 0,1, 0,1, 0,1Set the Transform Scale of the Right Hand to 0.1, 0.1, 0.1

    Configurar a câmera e os controles de usuário

  6. Remova o componente colisor do Sphere do lado direito clicando na engrenagem no componente colisor do Sphere e, em seguida, remover componente.Remove the Sphere Collider component from the Right Hand by clicking on the Gear in the Sphere Collider component, and then Remove Component.

    Configurar a câmera e os controles de usuário

  7. No painel hierarquia, arraste a câmera principal e os objetos à direita para o objeto pai da câmera .In the Hierarchy Panel drag the Main Camera and the Right Hand objects onto the Camera Parent object.

    Configurar a câmera e os controles de usuário

  8. Defina a posição de transformação da câmera principal e o objeto à direita como 0, 0, 0.Set the Transform Position of both the Main Camera and the Right Hand object to 0, 0, 0.

    Configurar a câmera e os controles de usuário

    Configurar a câmera e os controles de usuário

Capítulo 5 – configurar os objetos na cena do UnityChapter 5 - Set up the objects in the Unity scene

Agora você vai criar algumas formas básicas para sua cena, com as quais o usuário pode interagir.You will now create some basic shapes for your scene, with which the user can interact.

  1. Clique com o botão direito do mouse em uma área vazia no painel hierarquia e, em seguida, em objeto 3D, selecione plano.Right-click in an empty area in the Hierarchy Panel, then on 3D Object, then select Plane.

  2. Defina a posição de transformação plano como 0,-1, 0.Set the Plane Transform Position to 0, -1, 0.

  3. Defina a escala de transformação do plano como 5, 1, 5.Set the Plane Transform Scale to 5, 1, 5.

    Configurar os objetos na cena do Unity

  4. Crie um material básico para usar com o seu objeto plano , para que as outras formas sejam mais fáceis de ver.Create a basic material to use with your Plane object, so that the other shapes are easier to see. Navegue até o painel do projeto, clique com o botão direito do mouse em, em seguida, crie, seguido por pasta, para criar uma nova pasta.Navigate to your Project Panel, right-click, then Create, followed by Folder, to create a new folder. Nomeie os materiais de ti.Name it Materials.

    Configurar os objetos na cena do Unity Configurar os objetos na cena do Unity

  5. Abra a pasta materiais , clique com o botão direito do mouse em, clique em criar, em material, para criar um novo material.Open the Materials folder, then right-click, click Create, then Material, to create a new material. Nomeie-o como azul.Name it Blue.

    Configurar os objetos na cena do Unity Configurar os objetos na cena do Unity

  6. Com o novo material azul selecionado, examine o Inspetor e clique na janela retangular junto com albedo.With the new Blue material selected, look at the Inspector, and click the rectangular window alongside Albedo. Selecione uma cor azul (a imagem abaixo é uma cor hexadecimal: # 3592FFFF).Select a blue color (the one picture below is Hex Color: #3592FFFF). Clique no botão fechar depois de escolher.Click the close button once you have chosen.

    Configurar os objetos na cena do Unity

  7. Arraste o novo material da pasta materiais para o plano recém-criado, dentro de sua cena (ou solte-o no objeto plano dentro da hierarquia).Drag your new material from the Materials folder, onto your newly created Plane, within your scene (or drop it on the Plane object within the Hierarchy).

    Configurar os objetos na cena do Unity

  8. Clique com o botão direito do mouse em uma área vazia no painel hierarquia e, em seguida, em objeto 3D, cápsula.Right-click in an empty area in the Hierarchy Panel, then on 3D Object, Capsule.

    • Com a cápsula selecionada, altere sua posição de transformação para: -10, 1, 0.With the Capsule selected, change its Transform Position to: -10, 1, 0.
  9. Clique com o botão direito do mouse em uma área vazia no painel hierarquia e, em seguida, em objeto 3D, cubo.Right-click in an empty area in the Hierarchy Panel, then on 3D Object, Cube.

    • Com o cubo selecionado, altere sua posição de transformação para: 0, 0, 10.With the Cube selected, change its Transform Position to: 0, 0, 10.
  10. Clique com o botão direito do mouse em uma área vazia no painel hierarquia e, em seguida, em objeto 3D, esfera.Right-click in an empty area in the Hierarchy Panel, then on 3D Object, Sphere.

    • Com a esfera selecionada, altere sua posição de transformação para: 10, 0, 0.With the Sphere selected, change its Transform Position to: 10, 0, 0.

    Configurar os objetos na cena do Unity

    Observação

    Esses valores de posição são sugestões.These Position values are suggestions. Você tem a liberdade de definir as posições dos objetos para o que desejar, embora seja mais fácil para o usuário do aplicativo se as distâncias dos objetos não estiverem muito longe da câmera.You are free to set the positions of the objects to whatever you would like, though it is easier for the user of the application if the objects distances are not too far from the camera.

  11. Quando seu aplicativo está em execução, ele precisa ser capaz de identificar os objetos na cena, para conseguir isso, eles precisam ser marcados.When your application is running, it needs to be able to identify the objects within the scene, to achieve this, they need to be tagged. Selecione um dos objetos e, no painel Inspetor , clique em adicionar marca..., que vai alternar o Inspetor com as marcas & painel camadas .Select one of the objects, and in the Inspector panel, click Add Tag..., which will swap the Inspector with the Tags & Layers panel.

    Configurar os objetos na cena do Unity Set up the objects in the Unity Scene

  12. Clique no símbolo + (mais) e digite o nome da marca como ObjectInScene.Click the + (plus) symbol, then type the tag name as ObjectInScene.

    Configurar os objetos na cena do Unity

    Aviso

    Se você usar um nome diferente para sua marca, será necessário garantir que essa alteração também tenha DataFromAnalytics, objecttrigger e olhar, scripts mais tarde, para que seus objetos sejam encontrados e detectados dentro de sua cena.If you use a different name for your tag, you will need to ensure this change is also made the DataFromAnalytics, ObjectTrigger, and Gaze, scripts later, so that your objects are found, and detected, within your scene.

  13. Com a marca criada, agora você precisa aplicá-la a todos os três objetos.With the tag created, you now need to apply it to all three of your objects. Na hierarquia, mantenha a tecla Shift pressionada e, em seguida, clique nos objetos cápsula, cubo e esfera, no Inspetor, clique no menu suspenso junto com a marca e clique na marca ObjectInScene que você criou.From the Hierarchy, hold the Shift key, then click the Capsule, Cube, and Sphere, objects, then in the Inspector, click the dropdown menu alongside Tag, then click the ObjectInScene tag you created.

    Configurar os objetos na cena do Unity Set up the objects in the Unity Scene

Capítulo 6-criar a classe ApplicationInsightsTrackerChapter 6 - Create the ApplicationInsightsTracker class

O primeiro script que você precisa criar é ApplicationInsightsTracker, que é responsável por:The first script you need to create is ApplicationInsightsTracker, which is responsible for:

  1. Criar eventos com base nas interações do usuário para enviar ao Aplicativo Azure insights.Creating events based on user interactions to submit to Azure Application Insights.

  2. Criando nomes de evento apropriados, dependendo da interação do usuário.Creating appropriate Event names, depending on user interaction.

  3. Enviando eventos para a instância do serviço de Application Insights.Submitting events to the Application Insights Service instance.

Para criar esta classe:To create this class:

  1. Clique com o botão direito do mouse no painel Projeto e crie a > pasta.Right-click in the Project Panel, then Create > Folder. Nomeie a pasta scripts.Name the folder Scripts.

    Criar a classe ApplicationInsightsTracker Criar a classe ApplicationInsightsTracker

  2. Com a pasta scripts criada, clique duas vezes nela para abrir.With the Scripts folder created, double-click it, to open. Em seguida, dentro dessa pasta, clique com o botão direito do mouse em criar > script C#.Then, within that folder, right-click, Create > C# Script. Nomeie o script ApplicationInsightsTracker.Name the script ApplicationInsightsTracker.

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

  4. Atualize os namespaces na parte superior do script para que sejam os seguintes:Update namespaces at the top of the script to be as below:

        using Microsoft.ApplicationInsights;
        using Microsoft.ApplicationInsights.DataContracts;
        using Microsoft.ApplicationInsights.Extensibility;
        using UnityEngine;
    
  5. Dentro da classe, insira as seguintes variáveis:Inside the class insert the following variables:

        /// <summary>
        /// Allows this class to behavior like a singleton
        /// </summary>
        public static ApplicationInsightsTracker Instance;
    
        /// <summary>
        /// Insert your Instrumentation Key here
        /// </summary>
        internal string instrumentationKey = "Insert Instrumentation Key here";
    
        /// <summary>
        /// Insert your Application Id here
        /// </summary>
        internal string applicationId = "Insert Application Id here";
    
        /// <summary>
        /// Insert your API Key here
        /// </summary>
        internal string API_Key = "Insert API Key here";
    
        /// <summary>
        /// Represent the Analytic Custom Event object
        /// </summary>
        private TelemetryClient telemetryClient;
    
        /// <summary>
        /// Represent the Analytic object able to host gaze duration
        /// </summary>
        private MetricTelemetry metric;
    

    Observação

    Defina os valores de instrumentationKey, ApplicationId e API_Key adequadamente, usando as chaves de serviço do portal do Azure, conforme mencionado no capítulo 1, etapa 9 em diante.Set the instrumentationKey, applicationId and API_Key values appropriately, using the Service Keys from the Azure Portal as mentioned in Chapter 1, step 9 onwards.

  6. Em seguida, adicione os métodos Start () e ativo () , que serão chamados quando a classe for inicializada:Then add the Start() and Awake() methods, which will be called when the class initializes:

        /// <summary>
        /// Sets this class instance as a singleton
        /// </summary>
        void Awake()
        {
            Instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {
            // Instantiate telemetry and metric
            telemetryClient = new TelemetryClient();
    
            metric = new MetricTelemetry();
    
            // Assign the Instrumentation Key to the Event and Metric objects
            TelemetryConfiguration.Active.InstrumentationKey = instrumentationKey;
    
            telemetryClient.InstrumentationKey = instrumentationKey;
        }
    
  7. Adicione os métodos responsáveis por enviar os eventos e as métricas registradas pelo seu aplicativo:Add the methods responsible for sending the events and metrics registered by your application:

        /// <summary>
        /// Submit the Event to Azure Analytics using the event trigger object
        /// </summary>
        public void RecordProximityEvent(string objectName)
        {
            telemetryClient.TrackEvent(CreateEventName(objectName));
        }
    
        /// <summary>
        /// Uses the name of the object involved in the event to create 
        /// and return an Event Name convention
        /// </summary>
        public string CreateEventName(string name)
        {
            string eventName = $"User near {name}";
            return eventName;
        }
    
        /// <summary>
        /// Submit a Metric to Azure Analytics using the metric gazed object
        /// and the time count of the gaze
        /// </summary>
        public void RecordGazeMetrics(string objectName, int time)
        {
            // Output Console information about gaze.
            Debug.Log($"Finished gazing at {objectName}, which went for <b>{time}</b> second{(time != 1 ? "s" : "")}");
    
            metric.Name = $"Gazed {objectName}";
    
            metric.Value = time;
    
            telemetryClient.TrackMetric(metric);
        }
    
  8. 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.

Capítulo 7-criar o script olharChapter 7 - Create the Gaze script

O próximo script a ser criado é o script olhar .The next script to create is the Gaze script. Esse script é 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 script 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 um objeto com a marca ObjectInScene e, em seguida, contar quanto tempo o usuário gazes nesse objeto.In this case, the Raycast will need to identify if the user is looking at an object with the ObjectInScene tag, and then count how long the user gazes at that object.

  1. Clique duas vezes na pasta scripts para abri-la.Double-click on the Scripts folder, to open it.

  2. Clique com o botão direito do mouse na pasta scripts e clique em criar > script C#.Right-click inside the Scripts folder, click Create > C# Script. Nomeie o script olhar.Name the script Gaze.

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

  4. Substitua o código existente pelo seguinte:Replace the existing code with the following:

        using UnityEngine;
    
        public class Gaze : MonoBehaviour
        {
            /// <summary>
            /// Provides Singleton-like behavior to this class.
            /// </summary>
            public static Gaze Instance;
    
            /// <summary>
            /// Provides a reference to the object the user is currently looking at.
            /// </summary>
            public GameObject FocusedGameObject { get; private set; }
    
            /// <summary>
            /// Provides whether an object has been successfully hit by the raycast.
            /// </summary>
            public bool Hit { get; private set; }
    
            /// <summary>
            /// Provides a reference to compare whether the user is still looking at 
            /// the same object (and has not looked away).
            /// </summary>
            private GameObject _oldFocusedObject = null;
    
            /// <summary>
            /// Max Ray Distance
            /// </summary>
            private float _gazeMaxDistance = 300;
    
            /// <summary>
            /// Max Ray Distance
            /// </summary>
            private float _gazeTimeCounter = 0;
    
            /// <summary>
            /// The cursor object will be created when the app is running,
            /// this will store its values. 
            /// </summary>
            private GameObject _cursor;
        }
    
  5. 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.

        private void Awake()
        {
            // Set this class to behave similar to singleton
            Instance = this;
            _cursor = CreateCursor();
        }
    
        void Start()
        {
            FocusedGameObject = null;
        }
    
        /// <summary>
        /// Create a cursor object, to provide what the user
        /// is looking at.
        /// </summary>
        /// <returns></returns>
        private GameObject CreateCursor()    
        {
            GameObject newCursor = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    
            // Remove the collider, so it does not block raycast.
            Destroy(newCursor.GetComponent<SphereCollider>());
    
            newCursor.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
    
            newCursor.GetComponent<MeshRenderer>().material.color = 
            Color.HSVToRGB(0.0223f, 0.7922f, 1.000f);
    
            newCursor.SetActive(false);
            return newCursor;
        }
    
  6. Dentro da classe olhar , adicione o seguinte código no método Update () para projetar um Raycast e detectar a visita de destino:Inside the Gaze class, add the following code in the Update() method to project a Raycast and detect the target hit:

        /// <summary>
        /// Called every frame
        /// </summary>
        void Update()
        {
            // Set the old focused gameobject.
            _oldFocusedObject = FocusedGameObject;
    
            RaycastHit hitInfo;
    
            // Initialize Raycasting.
            Hit = Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hitInfo, _gazeMaxDistance);
    
            // Check whether raycast has hit.
            if (Hit == true)
            {
                // Check whether the hit has a collider.
                if (hitInfo.collider != null)
                {
                    // Set the focused object with what the user just looked at.
                    FocusedGameObject = hitInfo.collider.gameObject;
    
                    // Lerp the cursor to the hit point, which helps to stabilize the gaze.
                    _cursor.transform.position = Vector3.Lerp(_cursor.transform.position, hitInfo.point, 0.6f);
    
                    _cursor.SetActive(true);
                }
                else
                {
                    // Object looked on is not valid, set focused gameobject to null.
                    FocusedGameObject = null;
    
                    _cursor.SetActive(false);
                }
            }
            else
            {
                // No object looked upon, set focused gameobject to null.
                FocusedGameObject = null;
    
                _cursor.SetActive(false);
            }
    
            // Check whether the previous focused object is this same object. If so, reset the focused object.
            if (FocusedGameObject != _oldFocusedObject)
            {
                ResetFocusedObject();
            }
            // If they are the same, but are null, reset the counter. 
            else if (FocusedGameObject == null && _oldFocusedObject == null)
            {
                _gazeTimeCounter = 0;
            }
            // Count whilst the user continues looking at the same object.
            else
            {
                _gazeTimeCounter += Time.deltaTime;
            }
        }
    
  7. Adicione o método ResetFocusedObject () para enviar dados para Application insights quando o usuário tiver examinado um objeto.Add the ResetFocusedObject() method, to send data to Application Insights when the user has looked at an object.

        /// <summary>
        /// Reset the old focused object, stop the gaze timer, and send data if it
        /// is greater than one.
        /// </summary>
        public void ResetFocusedObject()
        {
            // Ensure the old focused object is not null.
            if (_oldFocusedObject != null)
            {
                // Only looking for objects with the correct tag.
                if (_oldFocusedObject.CompareTag("ObjectInScene"))
                {
                    // Turn the timer into an int, and ensure that more than zero time has passed.
                    int gazeAsInt = (int)_gazeTimeCounter;
    
                    if (gazeAsInt > 0)
                    {
                        //Record the object gazed and duration of gaze for Analytics
                        ApplicationInsightsTracker.Instance.RecordGazeMetrics(_oldFocusedObject.name, gazeAsInt);
                    }
                    //Reset timer
                    _gazeTimeCounter = 0;
                }
            }
        }
    
  8. Agora você concluiu o script olhar .You have now completed the Gaze script. Salve suas alterações no Visual Studio antes de retornar ao Unity.Save your changes in Visual Studio before returning to Unity.

Capítulo 8-criar a classe objecttriggerChapter 8 - Create the ObjectTrigger class

O próximo script que você precisa criar é objecttrigger, que é responsável por:The next script you need to create is ObjectTrigger, which is responsible for:

  • Adição de componentes necessários para a colisão na câmera principal.Adding components needed for collision to the Main Camera.
  • Detectando se a câmera está perto de um objeto marcado como ObjectInScene.Detecting if the camera is near an object tagged as ObjectInScene.

Para criar o script:To create the script:

  1. Clique duas vezes na pasta scripts para abri-la.Double-click on the Scripts folder, to open it.

  2. Clique com o botão direito do mouse na pasta scripts e clique em criar > script C#.Right-click inside the Scripts folder, click Create > C# Script. Nomeie o script loadtrigger.Name the script ObjectTrigger.

  3. Clique duas vezes no script para abri-lo com o Visual Studio.Double-click on the script to open it with Visual Studio. Substitua o código existente pelo seguinte:Replace the existing code with the following:

        using UnityEngine;
    
        public class ObjectTrigger : MonoBehaviour
        {
            private void Start()
            {
                // Add the Collider and Rigidbody components, 
                // and set their respective settings. This allows for collision.
                gameObject.AddComponent<SphereCollider>().radius = 1.5f;
    
                gameObject.AddComponent<Rigidbody>().useGravity = false;
            }
    
            /// <summary>
            /// Triggered when an object with a collider enters this objects trigger collider.
            /// </summary>
            /// <param name="collision">Collided object</param>
            private void OnCollisionEnter(Collision collision)
            {
                CompareTriggerEvent(collision, true);
            }
    
            /// <summary>
            /// Triggered when an object with a collider exits this objects trigger collider.
            /// </summary>
            /// <param name="collision">Collided object</param>
            private void OnCollisionExit(Collision collision)
            {
                CompareTriggerEvent(collision, false);
            }
    
            /// <summary>
            /// Method for providing debug message, and sending event information to InsightsTracker.
            /// </summary>
            /// <param name="other">Collided object</param>
            /// <param name="enter">Enter = true, Exit = False</param>
            private void CompareTriggerEvent(Collision other, bool enter)
            {
                if (other.collider.CompareTag("ObjectInScene"))
                {
                    string message = $"User is{(enter == true ? " " : " no longer ")}near <b>{other.gameObject.name}</b>";
    
                    if (enter == true)
                    {
                        ApplicationInsightsTracker.Instance.RecordProximityEvent(other.gameObject.name);
                    }
                    Debug.Log(message);
                }
            }
        }
    
  4. 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.

Capítulo 9-criar a classe DataFromAnalyticsChapter 9 - Create the DataFromAnalytics class

Agora, você precisará criar o script DataFromAnalytics , que é responsável por:You will now need to create the DataFromAnalytics script, which is responsible for:

  • Buscar dados de análise sobre qual objeto foi abordado pela câmera mais.Fetching analytics data about which object has been approached by the camera the most.
  • Usando as chaves de serviço, que permitem a comunicação com sua instância de serviço do aplicativo Azure insights.Using the Service Keys, that allow communication with your Azure Application Insights Service instance.
  • Classificação dos objetos em cena, de acordo com o qual tem a maior contagem de eventos.Sorting the objects in scene, according to which has the highest event count.
  • Alterar a cor do material, do objeto mais aproximado, para verde.Changing the material color, of the most approached object, to green.

Para criar o script:To create the script:

  1. Clique duas vezes na pasta scripts para abri-la.Double-click on the Scripts folder, to open it.

  2. Clique com o botão direito do mouse na pasta scripts e clique em criar > script C#.Right-click inside the Scripts folder, click Create > C# Script. Nomeie o script DataFromAnalytics.Name the script DataFromAnalytics.

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

  4. Insira os seguintes namespaces:Insert the following namespaces:

        using Newtonsoft.Json;
        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.Linq;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. No script, insira o seguinte:Inside the script, insert the following:

        /// <summary>
        /// Number of most recent events to be queried
        /// </summary>
        private int _quantityOfEventsQueried = 10;
    
        /// <summary>
        /// The timespan with which to query. Needs to be in hours.
        /// </summary>
        private int _timepspanAsHours = 24;
    
        /// <summary>
        /// A list of the objects in the scene
        /// </summary>
        private List<GameObject> _listOfGameObjectsInScene;
    
        /// <summary>
        /// Number of queries which have returned, after being sent.
        /// </summary>
        private int _queriesReturned = 0;
    
        /// <summary>
        /// List of GameObjects, as the Key, with their event count, as the Value.
        /// </summary>
        private List<KeyValuePair<GameObject, int>> _pairedObjectsWithEventCount = new List<KeyValuePair<GameObject, int>>();
    
        // Use this for initialization
        void Start()
        {
            // Find all objects in scene which have the ObjectInScene tag (as there may be other GameObjects in the scene which you do not want).
            _listOfGameObjectsInScene = GameObject.FindGameObjectsWithTag("ObjectInScene").ToList();
    
            FetchAnalytics();
        }
    
  6. Dentro da classe DataFromAnalytics , logo após o método Start () , adicione o método a seguir chamado FetchAnalytics ().Within the DataFromAnalytics class, right after the Start() method, add the following method called FetchAnalytics(). Esse método é responsável por preencher a lista de pares chave-valor, com um gameobject e um número de contagem de eventos de espaço reservado.This method is responsible for populating the list of key value pairs, with a GameObject and a placeholder event count number. Em seguida, ele inicializa a corotina GetWebRequest () .It then initializes the GetWebRequest() coroutine. A estrutura de consulta da chamada para Application insights pode ser encontrada dentro desse método também, como o ponto de extremidade da URL de consulta .The query structure of the call to Application Insights can be found within this method also, as the Query URL endpoint.

        private void FetchAnalytics()
        {
            // Iterate through the objects in the list
            for (int i = 0; i < _listOfGameObjectsInScene.Count; i++)
            {
                // The current event number is not known, so set it to zero.
                int eventCount = 0;
    
                // Add new pair to list, as placeholder, until eventCount is known.
                _pairedObjectsWithEventCount.Add(new KeyValuePair<GameObject, int>(_listOfGameObjectsInScene[i], eventCount));
    
                // Set the renderer of the object to the default color, white
                _listOfGameObjectsInScene[i].GetComponent<Renderer>().material.color = Color.white;
    
                // Create the appropriate object name using Insights structure
                string objectName = _listOfGameObjectsInScene[i].name;
    
                // Build the queryUrl for this object.
                string queryUrl = Uri.EscapeUriString(string.Format(
                    "https://api.applicationinsights.io/v1/apps/{0}/events/$all?timespan=PT{1}H&$search={2}&$select=customMetric/name&$top={3}&$count=true",
                    ApplicationInsightsTracker.Instance.applicationId, _timepspanAsHours, "Gazed " + objectName, _quantityOfEventsQueried));
    
    
                // Send this object away within the WebRequest Coroutine, to determine it is event count.
                StartCoroutine("GetWebRequest", new KeyValuePair<string, int>(queryUrl, i));
            }
        }
    
  7. Logo abaixo do método FetchAnalytics () , adicione um método chamado GetWebRequest (), que retorna um IEnumerator.Right below the FetchAnalytics() method, add a method called GetWebRequest(), which returns an IEnumerator. Esse método é responsável por solicitar o número de vezes que um evento, correspondente a um gameobject específico, foi chamado dentro de Application insights.This method is responsible for requesting the number of times an event, corresponding with a specific GameObject, has been called within Application Insights. Quando todas as consultas enviadas retornam, o método DetermineWinner () é chamado.When all the sent queries have returned, the DetermineWinner() method is called.

        /// <summary>
        /// Requests the data count for number of events, according to the
        /// input query URL.
        /// </summary>
        /// <param name="webQueryPair">Query URL and the list number count.</param>
        /// <returns></returns>
        private IEnumerator GetWebRequest(KeyValuePair<string, int> webQueryPair)
        {
            // Set the URL and count as their own variables (for readability).
            string url = webQueryPair.Key;
            int currentCount = webQueryPair.Value;
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(url))
            {
                DownloadHandlerBuffer handlerBuffer = new DownloadHandlerBuffer();
    
                unityWebRequest.downloadHandler = handlerBuffer;
    
                unityWebRequest.SetRequestHeader("host", "api.applicationinsights.io");
    
                unityWebRequest.SetRequestHeader("x-api-key", ApplicationInsightsTracker.Instance.API_Key);
    
                yield return unityWebRequest.SendWebRequest();
    
                if (unityWebRequest.isNetworkError)
                {
                    // Failure with web request.
                    Debug.Log("<color=red>Error Sending:</color> " + unityWebRequest.error);
                }
                else
                {
                    // This query has returned, so add to the current count.
                    _queriesReturned++;
    
                    // Initialize event count integer.
                    int eventCount = 0;
    
                    // Deserialize the response with the custom Analytics class.
                    Analytics welcome = JsonConvert.DeserializeObject<Analytics>(unityWebRequest.downloadHandler.text);
    
                    // Get and return the count for the Event
                    if (int.TryParse(welcome.OdataCount, out eventCount) == false)
                    {
                        // Parsing failed. Can sometimes mean that the Query URL was incorrect.
                        Debug.Log("<color=red>Failure to Parse Data Results. Check Query URL for issues.</color>");
                    }
                    else
                    {
                        // Overwrite the current pair, with its actual values, now that the event count is known.
                        _pairedObjectsWithEventCount[currentCount] = new KeyValuePair<GameObject, int>(_pairedObjectsWithEventCount[currentCount].Key, eventCount);
                    }
    
                    // If all queries (compared with the number which was sent away) have 
                    // returned, then run the determine winner method. 
                    if (_queriesReturned == _pairedObjectsWithEventCount.Count)
                    {
                        DetermineWinner();
                    }
                }
            }
        }
    
  8. O método Next é DetermineWinner (), que classifica a lista de pares gameobject e int , de acordo com a contagem de eventos mais alta.The next method is DetermineWinner(), which sorts the list of GameObject and Int pairs, according to the highest event count. Em seguida, ele altera a cor do material desse gameobject para verde (como comentários para ele com a contagem mais alta).It then changes the material color of that GameObject to green (as feedback for it having the highest count). Isso exibe uma mensagem com os resultados da análise.This displays a message with the analytics results.

        /// <summary>
        /// Call to determine the keyValue pair, within the objects list, 
        /// with the highest event count.
        /// </summary>
        private void DetermineWinner()
        {
            // Sort the values within the list of pairs.
            _pairedObjectsWithEventCount.Sort((x, y) => y.Value.CompareTo(x.Value));
    
            // Change its colour to green
            _pairedObjectsWithEventCount.First().Key.GetComponent<Renderer>().material.color = Color.green;
    
            // Provide the winner, and other results, within the console window. 
            string message = $"<b>Analytics Results:</b>\n " +
                $"<i>{_pairedObjectsWithEventCount.First().Key.name}</i> has the highest event count, " +
                $"with <i>{_pairedObjectsWithEventCount.First().Value.ToString()}</i>.\nFollowed by: ";
    
            for (int i = 1; i < _pairedObjectsWithEventCount.Count; i++)
            {
                message += $"{_pairedObjectsWithEventCount[i].Key.name}, " +
                    $"with {_pairedObjectsWithEventCount[i].Value.ToString()} events.\n";
            }
    
            Debug.Log(message);
        }
    
  9. Adicione a estrutura de classe que será usada para desserializar o objeto JSON, recebido do Application insights.Add the class structure which will be used to deserialize the JSON object, received from Application Insights. Adicione essas classes na parte inferior do arquivo de classe DataFromAnalytics , fora da definição de classe.Add these classes at the very bottom of your DataFromAnalytics class file, outside of the class definition.

        /// <summary>
        /// These classes represent the structure of the JSON response from Azure Insight
        /// </summary>
        [Serializable]
        public class Analytics
        {
            [JsonProperty("@odata.context")]
            public string OdataContext { get; set; }
    
            [JsonProperty("@odata.count")]
            public string OdataCount { get; set; }
    
            [JsonProperty("value")]
            public Value[] Value { get; set; }
        }
    
        [Serializable]
        public class Value
        {
            [JsonProperty("customMetric")]
            public CustomMetric CustomMetric { get; set; }
        }
    
        [Serializable]
        public class CustomMetric
        {
            [JsonProperty("name")]
            public string Name { get; set; }
        }
    
  10. 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.

Capítulo 10 – criar a classe de movimentoChapter 10 - Create the Movement class

O script de movimento é o próximo script que será necessário criar.The Movement script is the next script you will need to create. É responsável por:It is responsible for:

  • Mover a câmera principal de acordo com a direção em que a câmera está procurando.Moving the Main Camera according to the direction the camera is looking towards.
  • Adicionando todos os outros scripts a objetos de cena.Adding all other scripts to scene objects.

Para criar o script:To create the script:

  1. Clique duas vezes na pasta scripts para abri-la.Double-click on the Scripts folder, to open it.

  2. Clique com o botão direito do mouse na pasta scripts e clique em criar > script C#.Right-click inside the Scripts folder, click Create > C# Script. Nomeie a movimentação do script.Name the script Movement.

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

  4. Substitua o código existente pelo seguinte:Replace the existing code with the following:

        using UnityEngine;
        using UnityEngine.XR.WSA.Input;
    
        public class Movement : MonoBehaviour
        {
            /// <summary>
            /// The rendered object representing the right controller.
            /// </summary>
            public GameObject Controller;
    
            /// <summary>
            /// The movement speed of the user.
            /// </summary>
            public float UserSpeed;
    
            /// <summary>
            /// Provides whether source updates have been registered.
            /// </summary>
            private bool _isAttached = false;
    
            /// <summary>
            /// The chosen controller hand to use. 
            /// </summary>
            private InteractionSourceHandedness _handness = InteractionSourceHandedness.Right;
    
            /// <summary>
            /// Used to calculate and proposes movement translation.
            /// </summary>
            private Vector3 _playerMovementTranslation;
    
            private void Start()
            {
                // You are now adding components dynamically 
                // to ensure they are existing on the correct object  
    
                // Add all camera related scripts to the camera. 
                Camera.main.gameObject.AddComponent<Gaze>();
                Camera.main.gameObject.AddComponent<ObjectTrigger>();
    
                // Add all other scripts to this object.
                gameObject.AddComponent<ApplicationInsightsTracker>();
                gameObject.AddComponent<DataFromAnalytics>();
            }
    
            // Update is called once per frame
            void Update()
            {
    
            }
        }
    
  5. Dentro da classe de movimento , abaixo do método Update () vazio, insira os seguintes métodos que permitem ao usuário usar o controlador de mão para mover no espaço virtual:Within the Movement class, below the empty Update() method, insert the following methods that allow the user to use the hand controller to move in the virtual space:

        /// <summary>
        /// Used for tracking the current position and rotation of the controller.
        /// </summary>
        private void UpdateControllerState()
        {
    #if UNITY_WSA && UNITY_2017_2_OR_NEWER
            // Check for current connected controllers, only if WSA.
            string message = string.Empty;
    
            if (InteractionManager.GetCurrentReading().Length > 0)
            {
                foreach (var sourceState in InteractionManager.GetCurrentReading())
                {
                    if (sourceState.source.kind == InteractionSourceKind.Controller && sourceState.source.handedness == _handness)
                    {
                        // If a controller source is found, which matches the selected handness, 
                        // check whether interaction source updated events have been registered. 
                        if (_isAttached == false)
                        {
                            // Register events, as not yet registered.
                            message = "<color=green>Source Found: Registering Controller Source Events</color>";
                            _isAttached = true;
    
                            InteractionManager.InteractionSourceUpdated += InteractionManager_InteractionSourceUpdated;
                        }
    
                        // Update the position and rotation information for the controller.
                        Vector3 newPosition;
                        if (sourceState.sourcePose.TryGetPosition(out newPosition, InteractionSourceNode.Pointer) && ValidPosition(newPosition))
                        {
                            Controller.transform.localPosition = newPosition;
                        }
    
                        Quaternion newRotation;
    
                        if (sourceState.sourcePose.TryGetRotation(out newRotation, InteractionSourceNode.Pointer) && ValidRotation(newRotation))
                        {
                            Controller.transform.localRotation = newRotation;
                        }
                    }
                }
            }
            else
            {
                // Controller source not detected. 
                message = "<color=blue>Trying to detect controller source</color>";
    
                if (_isAttached == true)
                {
                    // A source was previously connected, however, has been lost. Disconnected
                    // all registered events. 
    
                    _isAttached = false;
    
                    InteractionManager.InteractionSourceUpdated -= InteractionManager_InteractionSourceUpdated;
    
                    message = "<color=red>Source Lost: Detaching Controller Source Events</color>";
                }
            }
    
            if(message != string.Empty)
            {
                Debug.Log(message);
            }
    #endif
        }
    
        /// <summary>
        /// This registered event is triggered when a source state has been updated.
        /// </summary>
        /// <param name="obj"></param>
        private void InteractionManager_InteractionSourceUpdated(InteractionSourceUpdatedEventArgs obj)
        {
            if (obj.state.source.handedness == _handness)
            {
                if(obj.state.thumbstickPosition.magnitude > 0.2f)
                {
                    float thumbstickY = obj.state.thumbstickPosition.y;
    
                    // Vertical Input.
                    if (thumbstickY > 0.3f || thumbstickY < -0.3f)
                    {
                        _playerMovementTranslation = Camera.main.transform.forward;
                        _playerMovementTranslation.y = 0;
                        transform.Translate(_playerMovementTranslation * UserSpeed * Time.deltaTime * thumbstickY, Space.World);
                    }
                }
            }
        }
    
        /// <summary>
        /// Check that controller position is valid. 
        /// </summary>
        /// <param name="inputVector3">The Vector3 to check</param>
        /// <returns>The position is valid</returns>
        private bool ValidPosition(Vector3 inputVector3)
        {
            return !float.IsNaN(inputVector3.x) && !float.IsNaN(inputVector3.y) && !float.IsNaN(inputVector3.z) && !float.IsInfinity(inputVector3.x) && !float.IsInfinity(inputVector3.y) && !float.IsInfinity(inputVector3.z);
        }
    
        /// <summary>
        /// Check that controller rotation is valid. 
        /// </summary>
        /// <param name="inputQuaternion">The Quaternion to check</param>
        /// <returns>The rotation is valid</returns>
        private bool ValidRotation(Quaternion inputQuaternion)
        {
            return !float.IsNaN(inputQuaternion.x) && !float.IsNaN(inputQuaternion.y) && !float.IsNaN(inputQuaternion.z) && !float.IsNaN(inputQuaternion.w) && !float.IsInfinity(inputQuaternion.x) && !float.IsInfinity(inputQuaternion.y) && !float.IsInfinity(inputQuaternion.z) && !float.IsInfinity(inputQuaternion.w);
        }   
    
  6. Adicione por último a chamada de método no método Update () .Lastly add the method call within the Update() method.

        // Update is called once per frame
        void Update()
        {
            UpdateControllerState();
        }
    
  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.

Capítulo 11-configurando as referências de scriptsChapter 11 - Setting up the scripts references

Neste capítulo, você precisa posicionar o script de movimento no pai da câmera e definir seus destinos de referência.In this Chapter you need to place the Movement script onto the Camera Parent and set its reference targets. Esse script manipulará a colocação dos outros scripts onde eles precisam ser.That script will then handle placing the other scripts where they need to be.

  1. Na pasta scripts do painel Projeto, arraste o script de movimento para o objeto pai da câmera , localizado no painel hierarquia.From the Scripts folder in the Project Panel, drag the Movement script to the Camera Parent object, located in the Hierarchy Panel.

    Configurando as referências de scripts na cena do Unity

  2. Clique no pai da câmera.Click on the Camera Parent. No painel hierarquia, arraste o objeto à direita do painel hierarquia para o destino de referência, controlador, no painel Inspetor.In the Hierarchy Panel, drag the Right Hand object from the Hierarchy Panel to the reference target, Controller, in the Inspector Panel. Defina a velocidade do usuário como 5, conforme mostrado na imagem abaixo.Set the User Speed to 5, as shown in the image below.

    Configurando as referências de scripts na cena do Unity

Capítulo 12-criar o projeto do UnityChapter 12 - Build the Unity project

Tudo o que é necessário para a seção do Unity deste projeto foi concluído, portanto, é hora de compilá-lo a partir do Unity.Everything needed for the Unity section of this project has now been completed, so it is time to build it from Unity.

  1. Navegue até configurações de compilação, (configurações de compilação de arquivo > ).Navigate to Build Settings, (File > Build Settings).

  2. Na janela configurações de compilação , clique em Compilar.From the Build Settings window, click Build.

    Compilar o projeto do Unity para a solução UWP

  3. Uma janela do Explorador de arquivos será exibida, solicitando um local para a compilação.A File Explorer window will pop-up, prompting you for a location for the build. Crie uma nova pasta (clicando em nova pasta no canto superior esquerdo) e nomeie-a como Build.Create a new folder (by clicking New Folder in the top-left corner), and name it BUILDS.

    Compilar o projeto do Unity para a solução UWP

    1. Abra a nova pasta Builds e crie outra pasta (usando a nova pasta mais uma vez) e nomeie-a como Sr _ Azure _ Application _ insights.Open the new BUILDS folder, and create another folder (using New Folder once more), and name it MR_Azure_Application_Insights.

      Compilar o projeto do Unity para a solução UWP

    2. Com a pasta Mr _ Azure _ Application _ insights selecionada, clique em Selecionar pasta.With the MR_Azure_Application_Insights folder selected, click Select Folder. O projeto levará um minuto ou mais para ser compilado.The project will take a minute or so to build.

  4. Após a compilação, o Explorador de arquivos aparecerá mostrando o local do novo projeto.Following Build, File Explorer will appear showing you the location of your new project.

Capítulo 13-implantar MR_Azure_Application_Insights aplicativo em seu computadorChapter 13 - Deploy MR_Azure_Application_Insights app to your machine

Para implantar o aplicativo de _ _ _ informações do aplicativo do Azure no seu computador local:To deploy the MR_Azure_Application_Insights app on your Local Machine:

  1. Abra o arquivo de solução do seu aplicativo Mr _ Azure _ Application _ insights no Visual Studio.Open the solution file of your MR_Azure_Application_Insights app in 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.

    Compilar o projeto do Unity para a solução UWP

  4. Vá para o menu Compilar e clique em implantar solução para Sideload o aplicativo em seu computador.Go to 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.Your app should now appear in the list of installed apps, ready to be launched.

  6. Inicie o aplicativo de realidade misturada.Launch the mixed reality application.

  7. Mova-se para a cena, abordando objetos e examinando-os, quando o serviço do Azure insights coletou dados de eventos suficientes, ele definirá o objeto que foi abordado o mais verde.Move around the scene, approaching objects and looking at them, when the Azure Insight Service has collected enough event data, it will set the object that has been approached the most to green.

Importante

Enquanto o tempo de espera médio para os eventos e as métricas a serem coletados pelo serviço leva cerca de 15 minutos, em algumas ocasiões, pode levar até 1 hora.While the average waiting time for the Events and Metrics to be collected by the Service takes around 15 min, in some occasions it might take up to 1 hour.

Capítulo 14-o portal do serviço Application InsightsChapter 14 - The Application Insights Service portal

Depois de fazer roaming da cena e gazed em vários objetos, você pode ver os dados coletados no portal do serviço de Application insights .Once you have roamed around the scene and gazed at several objects you can see the data collected in the Application Insights Service portal.

  1. Volte para o portal do serviço Application Insights.Go back to your Application Insights Service portal.

  2. Clique em Metrics Explorer.Click on Metrics Explorer.

    Examinando os dados coletados

  3. Ele será aberto em uma guia que contém o grafo que representa os eventos e as métricas relacionados ao seu aplicativo.It will open in a tab containing the graph which represent the Events and Metrics related to your application. Conforme mencionado acima, pode levar algum tempo (até 1 hora) para que os dados sejam exibidos no grafoAs mentioned above, it might take some time (up to 1 hour) for the data to be displayed in the graph

    Examinando os dados coletados

  4. Clique na barra de eventos no total de eventos por versão do aplicativo para ver uma análise detalhada dos eventos com seus nomes.Click on the Events bar in the Total of Events by Application Version, to see a detailed breakdown of the events with their names.

    Examinando os dados coletados

Seu aplicativo de serviço Application Insights concluídoYour finished your Application Insights Service application

Parabéns, você criou um aplicativo de realidade misturada que aproveita o serviço de Application Insights para monitorar a atividade do usuário em seu aplicativo.Congratulations, you built a mixed reality app that leverages the Application Insights Service to monitor user's activity within your app.

resultado do curso

Exercícios de bônusBonus Exercises

Exercício 1Exercise 1

Tente gerar, em vez de criar manualmente, os objetos ObjectInScene e definir suas coordenadas no plano dentro de seus scripts.Try spawning, rather than manually creating, the ObjectInScene objects and set their coordinates on the plane within your scripts. Dessa forma, você pode perguntar ao Azure qual era o objeto mais popular (seja de olhar ou resultados de proximidade) e gerar um extra desses objetos.In this way, you could ask Azure what the most popular object was (either from gaze or proximity results) and spawn an extra one of those objects.

Exercício 2Exercise 2

Classifique seus resultados de Application Insights por tempo, para que você obtenha os dados mais relevantes e implemente esses dados confidenciais em seu aplicativo.Sort your Application Insights results by time, so that you get the most relevant data, and implement that time sensitive data in your application.