Compartilhar via


HoloLens (1ª geração) e Azure 308: notificações entre dispositivos


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. Dessa forma, achamos que é importante continuar disponibilizando esses tutoriais para os desenvolvedores que ainda buscam obter diretrizes para o desenvolvimento visando esses dispositivos. Esses tutoriais não serão atualizados com os conjuntos de ferramentas mais recentes nem com as interações usadas para o HoloLens 2. Eles serão mantidos para continuar funcionando nos dispositivos compatíveis. Haverá uma nova série de tutoriais que serão postados no futuro que demonstrarão como desenvolver para o HoloLens 2. Este aviso será atualizado com um link para esses tutoriais quando eles forem postados.


produto final - início

Neste curso, você aprenderá a adicionar recursos de Hubs de Notificação a um aplicativo de realidade misturada usando Hubs de Notificação do Azure, Tabelas do Azure e Azure Functions.

Os Hubs de Notificação do Azure são um serviço da Microsoft que permite que os desenvolvedores enviem notificações por push direcionadas e personalizadas para qualquer plataforma, tudo com tecnologia na nuvem. Isso pode efetivamente permitir que os desenvolvedores se comuniquem com os usuários finais ou até mesmo se comuniquem entre vários aplicativos, dependendo do cenário. Para obter mais informações, visite a página Hubs de Notificação do Azure.

O Azure Functions é um serviço da Microsoft, que permite que os desenvolvedores executem pequenos pedaços de código, 'funções', no Azure. Isso fornece uma maneira de delegar trabalho à nuvem, em vez de ao seu aplicativo local, o que pode ter muitos benefícios. O Azure Functions dá suporte a várias linguagens de desenvolvimento, incluindo C#, F#, Node.js, Java e PHP. Para obter mais informações, visite a página do Azure Functions.

As Tabelas do Azure são um serviço de nuvem da Microsoft, que permite aos desenvolvedores armazenar dados estruturados não SQL na nuvem, tornando-os facilmente acessíveis em qualquer lugar. O serviço possui um design sem esquema, permitindo a evolução das tabelas conforme necessário e, portanto, é muito flexível. Para obter mais informações, visite a página Tabelas do Azure

Depois de concluir este curso, você terá um aplicativo de headset imersivo de realidade misturada e um aplicativo de PC desktop, que poderá fazer o seguinte:

  1. O aplicativo Desktop PC permitirá que o usuário mova um objeto no espaço 2D (X e Y), usando o mouse.

  2. A movimentação de objetos dentro do aplicativo para PC será enviada para a nuvem usando JSON, que estará na forma de uma cadeia de caracteres, contendo uma ID de objeto, tipo e informações de transformação (coordenadas X e Y).

  3. O aplicativo de realidade misturada, que tem uma cena idêntica ao aplicativo da área de trabalho, receberá notificações sobre o movimento do objeto do serviço Hubs de Notificação (que acaba de ser atualizado pelo aplicativo para PC Desktop).

  4. Ao receber uma notificação, que conterá a ID do objeto, o tipo e as informações de transformação, o aplicativo de realidade misturada aplicará as informações recebidas à sua própria cena.

Em sua aplicação, cabe a você como integrará os resultados ao seu design. Este curso foi desenvolvido para ensinar como integrar um Serviço do Azure ao seu projeto do Unity. É seu trabalho usar o conhecimento adquirido com este curso para aprimorar seu aplicativo de realidade misturada. Este curso é um tutorial independente, que não envolve diretamente nenhum outro Laboratório de Realidade Misturada.

Suporte a dispositivos

Curso HoloLens Headsets imersivos
MR e Azure 308: notificações entre dispositivos ✔️ ✔️

Observação

Embora este curso se concentre principalmente em headsets imersivos (VR) do Windows Mixed Reality, você também pode aplicar o que aprendeu neste curso ao Microsoft HoloLens. Ao acompanhar o curso, você verá anotações sobre as alterações que talvez precise empregar para dar suporte ao HoloLens. Ao usar o HoloLens, você pode observar algum eco durante a captura de voz.

Pré-requisitos

Observação

Este tutorial foi desenvolvido para desenvolvedores que têm experiência básica com Unity e C#. Esteja ciente também de que os pré-requisitos e as instruções escritas neste documento representam o que foi testado e verificado no momento da redação (maio de 2018). Você é livre para usar o software mais recente, conforme listado no artigo instalar as ferramentas , embora não se deva presumir que as informações neste curso corresponderão perfeitamente ao que você encontrará em softwares mais recentes do que os listados abaixo.

Recomendamos o seguinte hardware e software para este curso:

Antes de começar

  • Para evitar problemas ao criar este 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 no momento da compilação).
  • Você deve ser o proprietário do Portal do Desenvolvedor da Microsoft e do Portal de Registro de Aplicativos, caso contrário, não terá permissão para acessar o aplicativo no Capítulo 2.

Capítulo 1 – Criar um aplicativo no Portal do Desenvolvedor da Microsoft

Para usar o Serviço de Hubs de Notificação do Azure, você precisará criar um Aplicativo no Portal do Desenvolvedor da Microsoft, pois seu aplicativo precisará ser registrado, para que possa enviar e receber notificações.

  1. Faça logon no Portal do Desenvolvedor da Microsoft.

    Você precisará fazer login na sua conta da Microsoft.

  2. No Painel, clique em Criar um novo aplicativo.

    Criar um aplicativo

  3. Um pop-up aparecerá, no qual você precisa reservar um nome para seu novo aplicativo. Na caixa de texto, insira um nome apropriado; Se o nome escolhido estiver disponível, uma marca aparecerá à direita da caixa de texto. Depois de inserir um nome disponível, clique no botão Reservar nome do produto no canto inferior esquerdo do pop-up.

    Reverter um nome

  4. Com o aplicativo agora criado, você está pronto para passar para o próximo capítulo.

Capítulo 2 – Recuperar suas novas credenciais de aplicativos

Faça logon no Portal de Registro de Aplicativos, onde seu novo aplicativo será listado, e recupere as credenciais que serão usadas para configurar o Serviço de Hubs de Notificação no Portal do Azure.

  1. Navegue até o Portal de Registro de Aplicativos.

    Portal de registro de aplicativos

    Aviso

    Você precisará usar sua conta da Microsoft para fazer login.
    Essa deve ser a conta da Microsoft que você usou no capítulo anterior, com o portal do desenvolvedor da Windows Store.

  2. Você encontrará seu aplicativo na seção Meus aplicativos . Depois de encontrá-lo, clique nele e você será levado a uma nova página com o nome do aplicativo mais Registro.

    Seu aplicativo recém-registrado

  3. Role para baixo na página de registro para encontrar a seção Segredos do aplicativo e o SID do pacote do seu aplicativo. Copie ambos para uso com a configuração do Serviço de Hubs de Notificação do Azure no próximo capítulo.

    Segredos do aplicativo

Capítulo 3 – Configurar o Portal do Azure: criar o Serviço de Hubs de Notificação

Com as credenciais de seus aplicativos recuperadas, você precisará acessar o Portal do Azure, onde criará um Serviço de Hubs de Notificação do Azure.

  1. Faça logon no Portal do Azure.

    Observação

    Se você ainda não tiver uma conta do Azure, precisará criar uma. Se você estiver seguindo este tutorial em uma sala de aula ou laboratório, peça ajuda ao seu instrutor ou a um dos supervisores para configurar sua nova conta.

  2. Depois de fazer login, clique em Novo no canto superior esquerdo, procure por Hub de Notificação e clique em Enter.

    Pesquisar hub de notificação

    Observação

    A palavra Novo pode ter sido substituída por Criar um recurso, em portais mais recentes.

  3. A nova página fornecerá uma descrição do serviço Hubs de Notificação. Na parte inferior esquerda desse prompt, selecione o botão Criar para criar uma associação com esse serviço.

    Criar instância de Hubs de Notificação

  4. Depois de clicar em Criar:

    1. Insira o nome desejado para esta instância de serviço.

    2. Forneça um namespace que você poderá associar a este aplicativo.

    3. Selecione um Local.

    4. Escolha um grupo de recursos ou crie um novo. 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. É recomendável manter todos os serviços do Azure associados a um único projeto (por exemplo, como esses laboratórios) em um grupo de recursos comum).

      Se você quiser ler mais sobre os Grupos de Recursos do Azure, siga este link sobre como gerenciar um Grupo de Recursos.

    5. Selecione uma assinatura apropriada.

    6. Você também precisará confirmar que entendeu os Termos e Condições aplicados a este Serviço.

    7. Selecione Criar.

      Preencha os detalhes do serviço

  5. Depois de clicar em Criar, você terá que esperar que o serviço seja criado, isso pode levar um minuto.

  6. Uma notificação será exibida no portal assim que a instância de serviço for criada.

    notificação

  7. Clique no botão Ir para o recurso na notificação para explorar sua nova instância de serviço. Você será levado para sua nova instância de serviço do Hub de Notificação.

    Captura de tela que mostra o botão 'Ir para o recurso' destacado na janela de notificação.

  8. Na página de visão geral, na metade da página, clique em Windows (WNS). O painel à direita mudará para mostrar dois campos de texto, que exigem o SID do pacote e a chave de segurança, do aplicativo que você configurou anteriormente.

    Serviço de hubs recém-criado

  9. Depois de copiar os detalhes para os campos corretos, clique em Salvar e você receberá uma notificação quando o Hub de Notificação for atualizado com êxito.

    Copie os detalhes de segurança

Capítulo 4 – Configurar o Portal do Azure: criar o Serviço Tabela

Depois de criar sua instância do Serviço de Hubs de Notificação, navegue de volta para o Portal do Azure, onde você criará um Serviço de Tabelas do Azure criando um Recurso de Armazenamento.

  1. Se ainda não estiver conectado, faça logon no Portal do Azure.

  2. Uma vez logado, clique em Novo no canto superior esquerdo, procure por Conta de armazenamento e clique em Enter.

    Observação

    A palavra Novo pode ter sido substituída por Criar um recurso, em portais mais recentes.

  3. Selecione Conta de armazenamento – blob, arquivo, tabela, fila na lista.

    Pesquisar conta de armazenamento

  4. A nova página fornecerá uma descrição do serviço de conta de armazenamento. Na parte inferior esquerda desse prompt, selecione o botão Criar para criar uma instância desse serviço.

    Criar instância de armazenamento

  5. Depois de clicar em Criar, um painel aparecerá:

    1. Insira o Nome desejado para esta instância de serviço (deve ser todo em minúsculas).

    2. Em Modelo de implantação, clique em Gerenciador de recursos.

    3. Para Tipo de conta, usando o menu suspenso, selecione Armazenamento (uso geral v1).

    4. Selecione um local apropriado.

    5. Para o menu suspenso Replicação, selecione RA-GRS (armazenamento com redundância geográfica com acesso de leitura).

    6. Em Desempenho, clique em Padrão.

    7. Na seção Transferência segura necessária, selecione Desativado.

    8. No menu suspenso Assinatura , selecione uma assinatura apropriada.

    9. Escolha um grupo de recursos ou crie um novo. 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. É recomendável manter todos os serviços do Azure associados a um único projeto (por exemplo, como esses laboratórios) em um grupo de recursos comum).

      Se você quiser ler mais sobre os Grupos de Recursos do Azure, siga este link sobre como gerenciar um Grupo de Recursos.

    10. Deixe Redes virtuais como desabilitadas se essa for uma opção para você.

    11. Clique em Criar.

      Preencha os detalhes de armazenamento

  6. Depois de clicar em Criar, você terá que esperar que o serviço seja criado, isso pode levar um minuto.

  7. Uma notificação será exibida no portal assim que a instância de serviço for criada. Clique nas notificações para explorar sua nova instância de serviço.

    Nova notificação de armazenamento

  8. Clique no botão Ir para o recurso na notificação para explorar sua nova instância de serviço. Você será levado para a nova página de visão geral da instância do Serviço de Armazenamento.

    Captura de tela que mostra o botão 'Ir para o recurso' destacado na janela 'Implantação bem-sucedida'.

  9. Na página de visão geral, no lado direito, clique em Tabelas.

    Captura de tela que mostra onde selecionar Tabelas.

  10. O painel à direita mudará para mostrar as informações do serviço Tabela, em que você precisa adicionar uma nova tabela. Faça isso clicando no + botão Tabela no canto superior esquerdo.

    abrir Tabelas

  11. Uma nova página será mostrada, na qual você precisa inserir um nome de tabela. Esse é o nome que você usará para se referir aos dados em seu aplicativo em capítulos posteriores. Insira um nome apropriado e clique em OK.

    Criar nova tabela

  12. Depois que a nova tabela for criada, você poderá vê-la na página Serviço de tabela (na parte inferior).

    Nova tabela criada

Capítulo 5 – Concluindo a Tabela do Azure no Visual Studio

Agora que sua conta de armazenamento do serviço Tabela foi configurada, é hora de adicionar dados a ela, que serão usados para armazenar e recuperar informações. A edição de suas tabelas pode ser feita através do Visual Studio.

  1. Abra o Visual Studio.

  2. No menu, clique em Exibir>Cloud Explorer.

    Abra o Cloud Explorer

  3. O Cloud Explorer será aberto como um item encaixado (seja paciente, pois o carregamento pode levar tempo).

    Observação

    Se a Assinatura usada para criar suas Contas de Armazenamento não estiver visível, verifique se você tem:

    • Conectado à mesma conta que você usou para o Portal do Azure.

    • Selecionou sua assinatura na página de gerenciamento de contas (pode ser necessário aplicar um filtro nas configurações da sua conta):

      Encontrar assinatura

  4. Seus serviços de nuvem do Azure serão mostrados. Encontre Contas de Armazenamento e clique na seta à esquerda para expandir suas contas.

    Abrir contas de armazenamento

  5. Depois de expandida, sua conta de armazenamento recém-criada deve estar disponível. Clique na seta à esquerda do seu armazenamento e, quando ela for expandida, encontre Tabelas e clique na seta ao lado dela, para revelar a Tabela que você criou no último Capítulo. Clique duas vezes na sua tabela.

    Tabela de objetos de cena aberta

  6. Sua tabela será aberta no centro da janela do Visual Studio. Clique no ícone da tabela com o + (mais) nele.

    Adicionar nova tabela

  7. Uma janela aparecerá solicitando que você adicione entidade. Você criará três entidades no total, cada uma com várias propriedades. Você observará que PartitionKey e RowKey já são fornecidos, pois são usados pela tabela para localizar seus dados.

    Partição e chave de linha

  8. Atualize o valor de PartitionKey e RowKey da seguinte maneira (lembre-se de fazer isso para cada propriedade de linha adicionada, embora incremente a RowKey a cada vez):

    adicionar valores corretos

  9. Clique em Adicionar propriedade para adicionar linhas extras de dados. Faça com que sua primeira mesa vazia corresponda à tabela abaixo.

  10. Clique em OK quando tiver terminado.

    Clique em OK quando terminar

    Aviso

    Certifique-se de ter alterado o Tipo das entradas X, Y e Z para Duplo.

  11. Você notará que sua tabela agora tem uma linha de dados. Clique no + ícone (mais) novamente para adicionar outra entidade.

    primeira fila

  12. Crie uma propriedade adicional e defina os valores da nova entidade para corresponder aos mostrados abaixo.

    adicionar cubo

  13. Repita a última etapa para adicionar outra entidade. Defina os valores dessa entidade como os mostrados abaixo.

    adicionar cilindro

  14. Sua tabela agora deve se parecer com a abaixo.

    Tabela completa

  15. Você completou este capítulo. Certifique-se de salvar.

Capítulo 6 – Criar um Aplicativo de Funções do Azure

Crie um Aplicativo de Funções do Azure, que será chamado pelo aplicativo da área de trabalho para atualizar o serviço Tabela e enviar uma notificação por meio do Hub de Notificação.

Primeiro, você precisa criar um arquivo que permita que sua função do Azure carregue as bibliotecas necessárias.

  1. Abra o Bloco de Notas (pressione a tecla Windows e digite bloco de notas).

    Abra o bloco de notas

  2. Com o Bloco de Notas aberto, insira a estrutura JSON abaixo nele. Depois de fazer isso, salve-o em sua área de trabalho como project.json. É importante que a nomenclatura esteja correta: certifique-se de que NÃO tenha uma extensão de arquivo .txt . Esse arquivo define as bibliotecas que sua função usará, se você tiver usado o NuGet, ele parecerá familiar.

    {
    "frameworks": {
        "net46":{
        "dependencies": {
            "WindowsAzure.Storage": "7.0.0",
            "Microsoft.Azure.NotificationHubs" : "1.0.9",
            "Microsoft.Azure.WebJobs.Extensions.NotificationHubs" :"1.1.0"
        }
        }
    }
    }
    
  3. Faça logon no Portal do Azure.

  4. Depois de fazer login, clique em Novo no canto superior esquerdo e procure por Aplicativo de Funções, pressione Enter.

    Pesquisar por aplicativo de funções

    Observação

    A palavra Novo pode ter sido substituída por Criar um recurso, em portais mais recentes.

  5. A nova página fornecerá uma descrição do serviço de Aplicativo de Funções. Na parte inferior esquerda desse prompt, selecione o botão Criar para criar uma associação com esse serviço.

    Instância do aplicativo de funções

  6. Depois de clicar em Criar, preencha o seguinte:

    1. Em Nome do aplicativo, insira o nome desejado para essa instância de serviço.

    2. Selecione uma Assinatura.

    3. Selecione o tipo de preço apropriado para você, se esta for a primeira vez que cria um Serviço de Aplicativo de Funções, uma camada gratuita deverá estar disponível para você.

    4. Escolha um grupo de recursos ou crie um novo. 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. É recomendável manter todos os serviços do Azure associados a um único projeto (por exemplo, como esses laboratórios) em um grupo de recursos comum).

      Se você quiser ler mais sobre os Grupos de Recursos do Azure, siga este link sobre como gerenciar um Grupo de Recursos.

    5. Para SO, clique em Windows, pois essa é a plataforma pretendida.

    6. Selecione um Plano de Hospedagem (este tutorial está usando um Plano de Consumo.

    7. Selecione um local (escolha o mesmo local do armazenamento que você criou na etapa anterior)

    8. Para a seção Armazenamento , você deve selecionar o Serviço de Armazenamento criado na etapa anterior.

    9. Você não precisará do Application Insights neste aplicativo, portanto, sinta-se à vontade para deixá-lo desativado.

    10. Clique em Criar.

      Criar nova instância

  7. Depois de clicar em Criar , você terá que esperar que o serviço seja criado, isso pode levar um minuto.

  8. Uma notificação será exibida no portal assim que a instância de serviço for criada.

    nova notificação

  9. Clique nas notificações para explorar sua nova instância de serviço.

  10. Clique no botão Ir para o recurso na notificação para explorar sua nova instância de serviço.

    Captura de tela que mostra 'Implantação bem-sucedida' com o botão 'Ir para o recurso' realçado.

  11. Clique no + ícone (mais) ao lado de Funções para Criar novo.

    adicionar nova função

  12. No painel central, a janela de criação de função aparecerá. Ignore as informações na metade superior do painel e clique em Função personalizada, localizada perto da parte inferior (na área azul, conforme abaixo).

    função personalizada

  13. A nova página dentro da janela mostrará vários tipos de função. Role para baixo para exibir os tipos roxos e clique em Elemento HTTP PUT .

    http colocar link

    Importante

    Talvez seja necessário rolar mais para baixo na página (e essa imagem pode não parecer exatamente a mesma, se as atualizações do Portal do Azure tiverem ocorrido), no entanto, você está procurando um elemento chamado HTTP PUT.

  14. A janela HTTP PUT aparecerá, onde você precisa configurar a função (veja abaixo a imagem).

    1. Para Idioma, usando o menu suspenso, selecione C#.

    2. Para Nome, insira um nome apropriado.

    3. No menu suspenso Nível de autenticação, selecione Função.

    4. Para a seção Nome da tabela, você precisa usar o nome exato usado para criar o serviço Tabela anteriormente (incluindo as mesmas letras maiúsculas e minúsculas).

    5. Na seção Conexão da conta de armazenamento, use o menu suspenso e selecione sua conta de armazenamento a partir daí. Se não estiver lá, clique no novo hiperlink ao lado do título da seção para mostrar outro painel, onde sua conta de armazenamento deve ser listada.

      Captura de tela que mostra a seção de conexão da conta de armazenamento com o hiperlink 'Novo' selecionado.

  15. Clique em Criar e você receberá uma notificação de que suas configurações foram atualizadas com sucesso.

    Criar função

  16. Depois de clicar em Criar, você será redirecionado para o editor de funções.

    Atualizar código da função

  17. Insira o seguinte código no editor de funções (substituindo o código na função):

    #r "Microsoft.WindowsAzure.Storage"
    
    using System;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Table;
    using Microsoft.Azure.NotificationHubs;
    using Newtonsoft.Json;
    
    public static async Task Run(UnityGameObject gameObj, CloudTable table, IAsyncCollector<Notification> notification, TraceWriter log)
    {
        //RowKey of the table object to be changed
        string rowKey = gameObj.RowKey;
    
        //Retrieve the table object by its RowKey
        TableOperation operation = TableOperation.Retrieve<UnityGameObject>("UnityPartitionKey", rowKey); 
    
        TableResult result = table.Execute(operation);
    
        //Create a UnityGameObject so to set its parameters
        UnityGameObject existingGameObj = (UnityGameObject)result.Result; 
    
        existingGameObj.RowKey = rowKey;
        existingGameObj.X = gameObj.X;
        existingGameObj.Y = gameObj.Y;
        existingGameObj.Z = gameObj.Z;
    
        //Replace the table appropriate table Entity with the value of the UnityGameObject
        operation = TableOperation.Replace(existingGameObj); 
    
        table.Execute(operation);
    
        log.Verbose($"Updated object position");
    
        //Serialize the UnityGameObject
        string wnsNotificationPayload = JsonConvert.SerializeObject(existingGameObj);
    
        log.Info($"{wnsNotificationPayload}");
    
        var headers = new Dictionary<string, string>();
    
        headers["X-WNS-Type"] = @"wns/raw";
    
        //Send the raw notification to subscribed devices
        await notification.AddAsync(new WindowsNotification(wnsNotificationPayload, headers)); 
    
        log.Verbose($"Sent notification");
    }
    
    // This UnityGameObject represent a Table Entity
    public class UnityGameObject : TableEntity
    {
        public string Type { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
        public double Z { get; set; }
        public string RowKey { get; set; }
    }
    

    Observação

    Usando as bibliotecas incluídas, a função recebe o nome e o local do objeto que foi movido na cena do Unity (como um objeto C#, chamado UnityGameObject). Esse objeto é usado para atualizar os parâmetros do objeto na tabela criada. Depois disso, a função faz uma chamada para o serviço Hub de Notificação criado, que notifica todos os aplicativos inscritos.

  18. Com o código no lugar, clique em Salvar.

  19. Em seguida, clique no < ícone (seta), no lado direito da página.

    Abra o painel de upload

  20. Um painel deslizará pela direita. Nesse painel, clique em Carregar e um Navegador de Arquivos aparecerá.

  21. Navegue até o arquivo project.json e clique nele que você criou no Bloco de Notas anteriormente e clique no botão Abrir . Esse arquivo define as bibliotecas que sua função usará.

    Carregar JSON

  22. Quando o arquivo for carregado, ele aparecerá no painel à direita. Clicar nele irá abri-lo no Editor de funções . Deve ser exatamente igual à próxima imagem (abaixo da etapa 23).

  23. Em seguida, no painel à esquerda, abaixo de Funções, clique no link Integrar.

    função de integração

  24. Na próxima página, no canto superior direito, clique em Editor avançado (conforme abaixo).

    Abra o Editor Avançado

  25. Um arquivo function.json será aberto no painel central, que precisa ser substituído pelo seguinte trecho de código. Isso define a função que você está criando e os parâmetros passados para a função.

    {
    "bindings": [
        {
        "authLevel": "function",
        "type": "httpTrigger",
        "methods": [
            "get",
            "post"
        ],
        "name": "gameObj",
        "direction": "in"
        },
        {
        "type": "table",
        "name": "table",
        "tableName": "SceneObjectsTable",
        "connection": "mrnothubstorage_STORAGE",
        "direction": "in"
        },
        {
        "type": "notificationHub",
        "direction": "out",
        "name": "notification",
        "hubName": "MR_NotHub_ServiceInstance",
        "connection": "MRNotHubNS_DefaultFullSharedAccessSignature_NH",
        "platform": "wns"
        }
    ]
    }
    
  26. Seu editor agora deve se parecer com a imagem abaixo:

    Voltar ao editor padrão

  27. Você pode notar que os parâmetros de entrada que acabou de inserir podem não corresponder aos detalhes da tabela e do armazenamento e, portanto, precisarão ser atualizados com suas informações. Não faça isso aqui, pois é abordado a seguir. Basta clicar no link Editor padrão , no canto superior direito da página, para voltar.

  28. De volta ao editor Standard, clique em Armazenamento de Tabelas do Azure (tabela), em Entradas.

    Entradas de tabela

  29. Certifique-se de que o seguinte corresponda às suas informações, pois elas podem ser diferentes (há uma imagem abaixo das etapas a seguir):

    1. Nome da tabela: o nome da tabela que você criou no serviço Armazenamento do Azure, Tabelas.

    2. Conexão da conta de armazenamento: clique em novo, que aparece ao lado do menu suspenso, e um painel aparecerá à direita da janela.

      Captura de tela que mostra a janela Conta de Armazenamento com 'Criar novo' realçado no painel à direita da janela.

      1. Selecione sua Conta de Armazenamento, que você criou anteriormente para hospedar os Aplicativos de Funções.

      2. Você observará que o valor de conexão da Conta de Armazenamento foi criado.

      3. Certifique-se de pressionar Salvar quando terminar.

    3. A página Entradas agora deve corresponder à abaixo, mostrando suas informações.

      Entradas concluídas

  30. Em seguida, clique em Hub de Notificação do Azure (notificação) – em Saídas. Certifique-se de que os itens a seguir correspondam às suas informações, pois podem ser diferentes (há uma imagem abaixo das etapas a seguir):

    1. Nome do Hub de Notificação: esse é o nome da instância de serviço do Hub de Notificação, que você criou anteriormente.

    2. Conexão de namespace dos Hubs de Notificação: clique em novo, que aparece ao lado do menu suspenso.

      verificar saídas

    3. O pop-up Conexão será exibido (veja a imagem abaixo), onde você precisa selecionar o Namespace do Hub de Notificação, que você configurou anteriormente.

    4. Selecione o nome do Hub de Notificação no menu suspenso do meio.

    5. Defina o menu suspenso Política como DefaultFullSharedAccessSignature.

    6. Clique no botão Selecionar para voltar.

      Atualização de saída

  31. A página Saídas agora deve corresponder à página abaixo, mas com suas informações. Certifique-se de pressionar Salvar.

Aviso

Não edite o nome do Hub de Notificação diretamente (tudo isso deve ser feito usando o Editor Avançado, desde que você tenha seguido as etapas anteriores corretamente.

Captura de tela que mostra a página Saídas com informações gerais.

  1. Neste ponto, você deve testar a função, para garantir que ela esteja funcionando. Para fazer isso:

    1. Navegue até a página de função mais uma vez:

      Captura de tela que mostra a página de funções com a função recém-criada destacada.

    2. De volta à página de funções, clique na guia Teste no lado direito da página para abrir a folha Teste :

      Captura de tela da página de funções com 'Teste' destacado no lado direito.

    3. Na caixa de texto Corpo da solicitação da folha, cole o código abaixo:

      {  
          "Type":null,
          "X":3,
          "Y":0,
          "Z":1,
          "PartitionKey":null,
          "RowKey":"Obj2",
          "Timestamp":"0001-01-01T00:00:00+00:00",
          "ETag":null
      }
      
    4. Com o código de teste em vigor, clique no botão Executar no canto inferior direito e o teste será executado. Os logs de saída do teste aparecerão na área do console, abaixo do código da função.

      Captura de tela que mostra os logs de saída do teste na área do console.

    Aviso

    Se o teste acima falhar, você precisará verificar se seguiu exatamente as etapas acima, principalmente as configurações no painel de integração.

Capítulo 7 – Configurar o projeto do Desktop Unity

Importante

O aplicativo da área de trabalho que você está criando agora não funcionará no Unity Editor. Ele precisa ser executado fora do Editor, seguindo a Criação do aplicativo, usando o Visual Studio (ou o aplicativo implantado).

Veja a seguir uma configuração típica para desenvolvimento com Unity e realidade misturada e, como tal, é um bom modelo para outros projetos.

Configure e teste seu headset imersivo de realidade misturada.

Observação

Você não precisará de controladores de movimento para este curso. Se você precisar de suporte para configurar o headset imersivo, siga este link sobre como configurar Windows Mixed Reality.

  1. Abra o Unity e clique em Novo.

    Captura de tela da janela Projetos do Unity com o ícone de projeto 'Novo' destacado no canto superior direito.

  2. Você precisa fornecer um nome de projeto do Unity, inserir UnityDesktopNotifHub. Certifique-se de que o tipo de projeto esteja definido como 3D. Defina o local para algum lugar apropriado para você (lembre-se, mais perto dos diretórios raiz é melhor). Em seguida, clique em Criar projeto.

    criar projeto

  3. Com o Unity aberto, vale a pena verificar se o Editor de Scripts padrão está definido como Visual Studio. Vá para Editar>preferências e, na nova janela, navegue até Ferramentas externas. Altere o Editor de Script Externo para Visual Studio 2017. Feche a janela Preferências.

    definir ferramentas VS externas

  4. Em seguida, vá para Configurações de compilação de arquivo>e selecione Plataforma Universal do Windows e clique no botão Alternar plataforma para aplicar sua seleção.

    Trocar de plataforma

  5. Ainda em Configurações de compilação de arquivo>, certifique-se de que:

    1. O dispositivo de destino está definido como Qualquer dispositivo

      Este aplicativo será para sua área de trabalho, portanto, deve ser qualquer dispositivo

    2. O Tipo de Construção está definido como D3D

    3. O SDK está definido como Instalado mais recente

    4. A versão do Visual Studio está definida como Mais recente instalado

    5. Build and Run está definido como Computador Local

    6. Enquanto estiver aqui, vale a pena salvar a cena e adicioná-la à compilação.

      1. Faça isso selecionando Adicionar cenas abertas. Uma janela de salvamento aparecerá.

        Captura de tela que mostra o 'Adicionar cena aberta' destacado no canto superior direito.

      2. Crie uma nova pasta para esta e qualquer cena futura e, em seguida, selecione o botão Nova pasta , para criar uma nova pasta, nomeie-a como Cenas.

        Captura de tela que mostra uma nova pasta Cenas criada com 'Nova pasta' destacada no canto superior esquerdo.

      3. Abra a pasta Cenas recém-criada e, no campo de texto Nome do arquivo:, digite NH_Desktop_Scene e pressione Salvar.

        Novo NH_Desktop_Scene

    7. As configurações restantes, em Configurações de Build, devem ser deixadas como padrão por enquanto.

  6. Na mesma janela, clique no botão Configurações do player, isso abrirá o painel relacionado no espaço onde o Inspetor está localizado.

  7. Neste painel, algumas configurações precisam ser verificadas:

    1. Na guia Outras configurações:

      1. A versão do tempo de execução de script deve ser experimental (equivalente ao .NET 4.6)

      2. O back-end de script deve ser .NET

      3. O nível de compatibilidade da API deve ser .NET 4.6

        4.6 Versão NET

    2. Na guia Configurações de Publicação, em Recursos, marque:

      • InternetClient

        Captura de tela que mostra InternetClient selecionado em Recursos.

  8. De volta às configurações de compilação Os projetos do Unity C# não estão mais esmaecidos; marque a caixa de seleção ao lado dela.

  9. Feche a janela Configurações de Build.

  10. Salve sua cena e arquivo de projeto >Salvar cena / arquivo>salvar projeto.

    Importante

    Se você quiser ignorar o componente de configuração do Unity para este projeto (aplicativo da área de trabalho) e continuar direto para o código, sinta-se à vontade para baixar este .unitypackage, importá-lo para seu projeto como um pacote personalizado e continuar do Capítulo 9. Você ainda precisará adicionar os componentes de script.

Capítulo 8 – Importando as DLLs no Unity

Você usará o Armazenamento do Azure para Unity (que aproveita o SDK do .Net para Azure). Para obter mais informações, siga este link sobre o Armazenamento do Azure para Unity.

Atualmente, há um problema conhecido no Unity que exige que os plug-ins sejam reconfigurados após a importação. Essas etapas (4 a 7 nesta seção) não serão mais necessárias depois que o bug for resolvido.

Para importar o SDK para seu próprio projeto, verifique se você baixou o .unitypackage mais recente do GitHub. Em seguida, faça o seguinte:

  1. Adicione o .unitypackage ao Unity usando a opção de menu Pacote personalizado do pacote > de importação de ativos>.

  2. Na caixa Importar pacote do Unity que aparece, você pode selecionar tudo em Armazenamento de plug-ins>. Desmarque todo o resto, pois não é necessário para este curso.

    Importar para o pacote

  3. Clique no botão Importar para adicionar os itens ao seu projeto.

  4. Vá para a pasta Armazenamento em Plug-ins na visualização Projeto e selecione apenas os seguintes plug-ins:

    • Microsoft.Data.Edm
    • Microsoft.Data.OData
    • Microsoft.WindowsAzure.Storage
    • Newtonsoft.Json
    • System.Spatial

desmarque Qualquer plataforma

  1. Com esses plug-ins específicos selecionados, desmarque Qualquer plataforma e desmarque WSAPlayer e clique em Aplicar.

    Aplicar DLLs de plataforma

    Observação

    Estamos marcando esses plug-ins específicos para serem usados apenas no Unity Editor. Isso ocorre porque há versões diferentes dos mesmos plug-ins na pasta WSA que serão usadas depois que o projeto for exportado do Unity.

  2. Na pasta Plug-in de armazenamento , selecione apenas:

    • Microsoft.Data.Services.Client

      Definir Não processar para DLLs

  3. Marque a caixa Não processar em Configurações da plataforma e clique em Aplicar.

    não aplicar nenhum processamento

    Observação

    Estamos marcando este plug-in como "Não processar", porque o patcher de assembly do Unity tem dificuldade em processar esse plug-in. O plug-in ainda funcionará mesmo que não seja processado.

Capítulo 9 – Criar a classe TableToScene no projeto do Desktop Unity

Agora você precisa criar os scripts que contêm o código para executar esse aplicativo.

O primeiro script que você precisa criar é TableToScene, que é responsável por:

  • Leitura de entidades na Tabela do Azure.
  • Usando os dados da tabela, determine quais objetos devem ser gerados e em qual posição.

O segundo script que você precisa criar é o CloudScene, que é responsável por:

  • Registrando o evento de clique com o botão esquerdo, para permitir que o usuário arraste objetos pela cena.
  • Serializar os dados do objeto dessa cena do Unity e enviá-los para o Aplicativo de Funções do Azure.

Para criar essa classe:

  1. Clique com o botão direito do mouse na pasta de ativos localizada no painel Projeto, Criar>pasta. Nomeie a pasta Scripts.

    Criar pasta de scripts

    Criar pasta de scripts 2

  2. Clique duas vezes na pasta recém-criada para abri-la.

  3. Clique com o botão direito do mouse dentro da pasta Scripts, clique em Criar>Script C#. Nomeie o script TableToScene.

    Captura de tela que mostra como criar o novo script 'TableToScene'.Renomeação de TableToScene

  4. Clique duas vezes no script para abri-lo no Visual Studio 2017.

  5. Adicione os seguintes namespaces:

    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Auth;
    using Microsoft.WindowsAzure.Storage.Table;
    using UnityEngine;
    
  6. Dentro da classe, insira as seguintes variáveis:

        /// <summary>    
        /// allows this class to behave like a singleton
        /// </summary>    
        public static TableToScene instance;
    
        /// <summary>    
        /// Insert here you Azure Storage name     
        /// </summary>    
        private string accountName = " -- Insert your Azure Storage name -- ";
    
        /// <summary>    
        /// Insert here you Azure Storage key    
        /// </summary>    
        private string accountKey = " -- Insert your Azure Storage key -- ";
    

    Observação

    Substitua o valor accountName pelo nome do Serviço de Armazenamento do Azure e o valor accountKey pelo valor da chave encontrado no Serviço de Armazenamento do Azure, no Portal do Azure (veja a imagem abaixo).

    Buscar chave de conta

  7. Agora adicione os métodos Start() e Awake() para inicializar a classe.

        /// <summary>
        /// Triggers before initialization
        /// </summary>
        void Awake()
        {
            // static instance of this class
            instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {  
            // Call method to populate the scene with new objects as 
            // pecified in the Azure Table
            PopulateSceneFromTableAsync();
        }
    
  8. Na classe TableToScene, adicione o método que recuperará os valores da Tabela do Azure e use-os para gerar os primitivos apropriados na cena.

        /// <summary>    
        /// Populate the scene with new objects as specified in the Azure Table    
        /// </summary>    
        private async void PopulateSceneFromTableAsync()
        {
            // Obtain credentials for the Azure Storage
            StorageCredentials creds = new StorageCredentials(accountName, accountKey);
    
            // Storage account
            CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true);
    
            // Storage client
            CloudTableClient client = account.CreateCloudTableClient(); 
    
            // Table reference
            CloudTable table = client.GetTableReference("SceneObjectsTable");
    
            TableContinuationToken token = null;
    
            // Query the table for every existing Entity
            do
            {
                // Queries the whole table by breaking it into segments
                // (would happen only if the table had huge number of Entities)
                TableQuerySegment<AzureTableEntity> queryResult = await table.ExecuteQuerySegmentedAsync(new TableQuery<AzureTableEntity>(), token); 
    
                foreach (AzureTableEntity entity in queryResult.Results)
                {
                    GameObject newSceneGameObject = null;
                    Color newColor;
    
                    // check for the Entity Type and spawn in the scene the appropriate Primitive
                    switch (entity.Type)
                    {
                        case "Cube":
                            // Create a Cube in the scene
                            newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
                            newColor = Color.blue;
                            break;
    
                        case "Sphere":
                            // Create a Sphere in the scene
                            newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                            newColor = Color.red;
                            break;
    
                        case "Cylinder":
                            // Create a Cylinder in the scene
                            newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                            newColor = Color.yellow;
                            break;
                        default:
                            newColor = Color.white;
                            break;
                    }
    
                    newSceneGameObject.name = entity.RowKey;
    
                    newSceneGameObject.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Diffuse"))
                    {
                        color = newColor
                    };
    
                    //check for the Entity X,Y,Z and move the Primitive at those coordinates
                    newSceneGameObject.transform.position = new Vector3((float)entity.X, (float)entity.Y, (float)entity.Z);
                }
    
                // if the token is null, it means there are no more segments left to query
                token = queryResult.ContinuationToken;
            }
    
            while (token != null);
        }
    
  9. Fora da classe TableToScene, você precisa definir a classe usada pelo aplicativo para serializar e desserializar as entidades de tabela.

        /// <summary>
        /// This objects is used to serialize and deserialize the Azure Table Entity
        /// </summary>
        [System.Serializable]
        public class AzureTableEntity : TableEntity
        {
            public AzureTableEntity(string partitionKey, string rowKey)
                : base(partitionKey, rowKey) { }
    
            public AzureTableEntity() { }
            public string Type { get; set; }
            public double X { get; set; }
            public double Y { get; set; }
            public double Z { get; set; }
        }
    
  10. Certifique-se de salvar antes de voltar para o Editor do Unity.

  11. Clique na Câmera principal no painel Hierarquia , para que suas propriedades apareçam no Inspetor.

  12. Com a pasta Scripts aberta, selecione o arquivo TableToScene do script e arraste-o para a Câmera principal. O resultado deve ser o seguinte:

    Adicionar script à câmera principal

Capítulo 10 – Criar a classe CloudScene no projeto do Desktop Unity

O segundo script que você precisa criar é o CloudScene, que é responsável por:

  • Registrando o evento de clique com o botão esquerdo, para permitir que o usuário arraste objetos pela cena.

  • Serializar os dados do objeto dessa cena do Unity e enviá-los para o Aplicativo de Funções do Azure.

Para criar o segundo script:

  1. Clique com o botão direito do mouse dentro da pasta Scripts , clique em Criar, Script C#. Nomeie o script CloudScene

    Captura de tela que mostra como criar o novo script 'CloudScene'.renomear CloudScene

  2. Adicione os seguintes namespaces:

    using Newtonsoft.Json;
    using System.Collections;
    using System.Text;
    using System.Threading.Tasks;
    using UnityEngine;
    using UnityEngine.Networking;
    
  3. Insira as seguintes variáveis:

        /// <summary>
        /// Allows this class to behave like a singleton
        /// </summary>
        public static CloudScene instance;
    
        /// <summary>
        /// Insert here you Azure Function Url
        /// </summary>
        private string azureFunctionEndpoint = "--Insert here you Azure Function Endpoint--";
    
        /// <summary>
        /// Flag for object being moved
        /// </summary>
        private bool gameObjHasMoved;
    
        /// <summary>
        /// Transform of the object being dragged by the mouse
        /// </summary>
        private Transform gameObjHeld;
    
        /// <summary>
        /// Class hosted in the TableToScene script
        /// </summary>
        private AzureTableEntity azureTableEntity;
    
  4. Substitua o valor azureFunctionEndpoint pela URL do Aplicativo de Funções do Azure encontrada no Serviço de Aplicativo de Funções do Azure, no Portal do Azure, conforme mostrado na imagem abaixo:

    obter URL da função

  5. Agora adicione os métodos Start() e Awake() para inicializar a classe.

        /// <summary>
        /// Triggers before initialization
        /// </summary>
        void Awake()
        {
            // static instance of this class
            instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {
            // initialise an AzureTableEntity
            azureTableEntity = new AzureTableEntity();
        }
    
  6. No método Update(), adicione o código a seguir que detectará a entrada e o arrasto do mouse, o que, por sua vez, moverá GameObjects na cena. Se o usuário tiver arrastado e soltado um objeto, ele passará o nome e as coordenadas do objeto para o método UpdateCloudScene(), que chamará o serviço Azure Function App, que atualizará a tabela do Azure e disparará a notificação.

        /// <summary>
        /// Update is called once per frame
        /// </summary>
        void Update()
        {
            //Enable Drag if button is held down
            if (Input.GetMouseButton(0))
            {
                // Get the mouse position
                Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10);
    
                Vector3 objPos = Camera.main.ScreenToWorldPoint(mousePosition);
    
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    
                RaycastHit hit;
    
                // Raycast from the current mouse position to the object overlapped by the mouse
                if (Physics.Raycast(ray, out hit))
                {
                    // update the position of the object "hit" by the mouse
                    hit.transform.position = objPos;
    
                    gameObjHasMoved = true;
    
                    gameObjHeld = hit.transform;
                }
            }
    
            // check if the left button mouse is released while holding an object
            if (Input.GetMouseButtonUp(0) && gameObjHasMoved)
            {
                gameObjHasMoved = false;
    
                // Call the Azure Function that will update the appropriate Entity in the Azure Table
                // and send a Notification to all subscribed Apps
                Debug.Log("Calling Azure Function");
    
                StartCoroutine(UpdateCloudScene(gameObjHeld.name, gameObjHeld.position.x, gameObjHeld.position.y, gameObjHeld.position.z));
            }
        }
    
  7. Agora adicione o método UpdateCloudScene(), conforme abaixo:

        private IEnumerator UpdateCloudScene(string objName, double xPos, double yPos, double zPos)
        {
            WWWForm form = new WWWForm();
    
            // set the properties of the AzureTableEntity
            azureTableEntity.RowKey = objName;
    
            azureTableEntity.X = xPos;
    
            azureTableEntity.Y = yPos;
    
            azureTableEntity.Z = zPos;
    
            // Serialize the AzureTableEntity object to be sent to Azure
            string jsonObject = JsonConvert.SerializeObject(azureTableEntity);
    
            using (UnityWebRequest www = UnityWebRequest.Post(azureFunctionEndpoint, jsonObject))
            {
                byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(jsonObject);
    
                www.uploadHandler = new UploadHandlerRaw(jsonToSend);
    
                www.uploadHandler.contentType = "application/json";
    
                www.downloadHandler = new DownloadHandlerBuffer();
    
                www.SetRequestHeader("Content-Type", "application/json");
    
                yield return www.SendWebRequest();
    
                string response = www.responseCode.ToString();
            }
        }
    
  8. Salve o código e retorne ao Unity

  9. Arraste o script CloudScene para a Câmera Principal.

    1. Clique na Câmera principal no painel Hierarquia , para que suas propriedades apareçam no Inspetor.

    2. Com a pasta Scripts aberta, selecione o script CloudScene e arraste-o para a Câmera Principal. O resultado deve ser o seguinte:

      Arraste o script de nuvem para a câmera principal

Capítulo 11 – Criar o projeto da área de trabalho para UWP

Tudo o que é necessário para a seção Unity deste projeto já foi concluído.

  1. Navegue até Configurações de compilação (Configurações de compilação de arquivo>).

  2. Na janela Configurações de Compilação, clique em Compilar.

    Captura de tela que mostra a janela Configurações de Build com a Plataforma Universal do Windows selecionada e o botão 'Build' destacado no canto inferior direito.

  3. Uma janela do Explorador de Arquivos aparecerá, solicitando um local para compilar. Crie uma nova pasta (clicando em Nova pasta no canto superior esquerdo) e nomeie-a como BUILDS.

    nova pasta para build

    1. Abra a nova pasta BUILDS e crie outra pasta (usando Nova pasta mais uma vez) e nomeie-a NH_Desktop_App.

      Nome da pasta NH_Desktop_App

    2. Com o NH_Desktop_App selecionado. clique em Selecionar pasta. O projeto levará cerca de um minuto para ser construído.

  4. Após a compilação, o Explorador de Arquivos aparecerá mostrando a localização do seu novo projeto. No entanto, não há necessidade de abri-lo, pois você precisa criar o outro projeto do Unity primeiro, nos próximos capítulos.

Capítulo 12 – Configurar o Projeto Unity de Realidade Misturada

A seguir está uma configuração típica para desenvolvimento com a realidade misturada e, como tal, é um bom modelo para outros projetos.

  1. Abra o Unity e clique em Novo.

    Captura de tela que mostra a janela Projetos do Unity com 'Novo' destacado no canto superior direito.

  2. Agora você precisará fornecer um nome de projeto do Unity, inserir UnityMRNotifHub. Certifique-se de que o tipo de projeto esteja definido como 3D. Defina o local para algum lugar apropriado para você (lembre-se, mais perto dos diretórios raiz é melhor). Em seguida, clique em Criar projeto.

    nome UnityMRNotifHub

  3. Com o Unity aberto, vale a pena verificar se o Editor de Scripts padrão está definido como Visual Studio. Vá para Editar>preferências e, na nova janela, navegue até Ferramentas externas. Altere o Editor de Script Externo para Visual Studio 2017. Feche a janela Preferências.

    definir editor externo como VS

  4. Em seguida, vá para Configurações de Build de Arquivo>e alterne a plataforma para Plataforma Universal do Windows, clicando no botão Alternar Plataforma.

    alternar plataformas para UWP

  5. Vá para Configurações de Build de Arquivo>e certifique-se de que:

    1. O dispositivo de destino está definido como Qualquer dispositivo

      Para o Microsoft HoloLens, defina Dispositivo de Destino como HoloLens.

    2. O Tipo de Construção está definido como D3D

    3. O SDK está definido como Instalado mais recente

    4. A versão do Visual Studio está definida como Mais recente instalado

    5. Build and Run está definido como Computador Local

    6. Enquanto estiver aqui, vale a pena salvar a cena e adicioná-la à compilação.

      1. Faça isso selecionando Adicionar cenas abertas. Uma janela de salvamento aparecerá.

        Captura de tela que mostra a janela Configurações de construção com o botão 'Adicionar cenas abertas' destacado no canto superior direito.

      2. Crie uma nova pasta para esta e qualquer cena futura e, em seguida, selecione o botão Nova pasta , para criar uma nova pasta, nomeie-a como Cenas.

        Captura de tela que mostra 'Nova pasta' destacada no canto superior esquerdo da janela Salvar cena.

      3. Abra a pasta Cenas recém-criada e, no campo de texto Nome do arquivo:, digite NH_MR_Scene e pressione Salvar.

        Nova cena - NH_MR_Scene

    7. As configurações restantes, em Configurações de Build, devem ser deixadas como padrão por enquanto.

  6. Na mesma janela, clique no botão Configurações do player, isso abrirá o painel relacionado no espaço onde o Inspetor está localizado.

    Abra as configurações do player

  7. Neste painel, algumas configurações precisam ser verificadas:

    1. Na guia Outras configurações:

      1. A versão do tempo de execução de script deve ser experimental (equivalente ao .NET 4.6)

      2. O back-end de script deve ser .NET

      3. O nível de compatibilidade da API deve ser .NET 4.6

        Compatibilidade de API

    2. Mais abaixo no painel, em Configurações XR (encontradas abaixo de Configurações de Publicação), marque Realidade Virtual com Suporte, verifique se o SDK do Windows Mixed Reality foi adicionado

      Atualizar configurações de XR

    3. Na guia Configurações de Publicação, em Recursos, marque:

      • InternetClient

        Captura de tela que mostra a guia Configurações de Publicação com InternetClient marcada.

  8. De volta às Configurações de Build, os Projetos C# do Unity não estão mais esmaecidos: marque a caixa de seleção ao lado disso.

  9. Com essas alterações feitas, feche a janela Configurações de Compilação.

  10. Salve sua cena e arquivo de projeto >Salvar cena / arquivo>salvar projeto.

    Importante

    Se você quiser ignorar o componente de configuração do Unity para este projeto (aplicativo de realidade misturada) e continuar direto no código, sinta-se à vontade para baixar este .unitypackage, importá-lo para seu projeto como um pacote personalizado e continuar do Capítulo 14. Você ainda precisará adicionar os componentes de script.

Capítulo 13 – Importando as DLLs no Projeto Unity de Realidade Misturada

Você usará a biblioteca do Armazenamento do Azure para Unity (que usa o SDK do .Net para Azure). Siga este link sobre como usar o Armazenamento do Azure com o Unity. Atualmente, há um problema conhecido no Unity que exige que os plug-ins sejam reconfigurados após a importação. Essas etapas (4 a 7 nesta seção) não serão mais necessárias depois que o bug for resolvido.

Para importar o SDK para seu próprio projeto, verifique se você baixou o .unitypackage mais recente. Em seguida, faça o seguinte:

  1. Adicione o .unitypackage que você baixou acima ao Unity usando a opção de menu Pacote personalizado do pacote>de importação de ativos.>

  2. Na caixa Importar pacote do Unity que aparece, você pode selecionar tudo em Armazenamento de plug-ins>.

    pacote de importação

  3. Clique no botão Importar para adicionar os itens ao seu projeto.

  4. Vá para a pasta Armazenamento em Plug-ins na visualização Projeto e selecione apenas os seguintes plug-ins:

    • Microsoft.Data.Edm
    • Microsoft.Data.OData
    • Microsoft.WindowsAzure.Storage
    • Newtonsoft.Json
    • System.Spatial

    Selecione os plug-ins

  5. Com esses plug-ins específicos selecionados, desmarque Qualquer plataforma e desmarque WSAPlayer e clique em Aplicar.

    Aplicar alterações de plataforma

    Observação

    Você está marcando esses plug-ins específicos para serem usados apenas no Editor do Unity. Isso ocorre porque há versões diferentes dos mesmos plug-ins na pasta WSA que serão usadas depois que o projeto for exportado do Unity.

  6. Na pasta Plug-in de armazenamento , selecione apenas:

    • Microsoft.Data.Services.Client

      Selecione o cliente de serviços de dados

  7. Marque a caixa Não processar em Configurações da plataforma e clique em Aplicar.

    não processe

    Observação

    Você está marcando este plug-in como "Não processar" porque o patcher de assembly do Unity tem dificuldade em processar esse plug-in. O plug-in ainda funcionará mesmo que não seja processado.

Capítulo 14 – Criando a classe TableToScene no projeto Unity de realidade misturada

A classe TableToScene é idêntica à explicada no Capítulo 9. Crie a mesma classe no Projeto Unity de realidade misturada seguindo o mesmo procedimento explicado no Capítulo 9.

Depois de concluir este capítulo, ambos os seus projetos do Unity terão essa classe configurada na câmera principal.

Capítulo 15 – Criando a classe NotificationReceiver no Projeto Unity de Realidade Misturada

O segundo script que você precisa criar é NotificationReceiver, que é responsável por:

  • Registrando o aplicativo no Hub de Notificação na inicialização.
  • Escutar notificações provenientes do Hub de Notificação.
  • Desserialização dos dados do objeto de notificações recebidas.
  • Mova os GameObjects na cena, com base nos dados desserializados.

Para criar o script NotificationReceiver :

  1. Clique com o botão direito do mouse dentro da pasta Scripts , clique em Criar, Script C#. Nomeie o script NotificationReceiver.

    Criar novo script C#nomeie-o como NotificationReceiver

  2. Clique duas vezes no script para abri-lo.

  3. Adicione os seguintes namespaces:

    //using Microsoft.WindowsAzure.Messaging;
    using Newtonsoft.Json;
    using System;
    using System.Collections;
    using UnityEngine;
    
    #if UNITY_WSA_10_0 && !UNITY_EDITOR
    using Windows.Networking.PushNotifications;
    #endif
    
  4. Insira as seguintes variáveis:

        /// <summary>
        /// allows this class to behave like a singleton
        /// </summary>
        public static NotificationReceiver instance;
    
        /// <summary>
        /// Value set by the notification, new object position
        /// </summary>
        Vector3 newObjPosition;
    
        /// <summary>
        /// Value set by the notification, object name
        /// </summary>
        string gameObjectName;
    
        /// <summary>
        /// Value set by the notification, new object position
        /// </summary>
        bool notifReceived;
    
        /// <summary>
        /// Insert here your Notification Hub Service name 
        /// </summary>
        private string hubName = " -- Insert the name of your service -- ";
    
        /// <summary>
        /// Insert here your Notification Hub Service "Listen endpoint"
        /// </summary>
        private string hubListenEndpoint = "-Insert your Notification Hub Service Listen endpoint-";
    
  5. Substitua o valor hubName pelo nome do Serviço de Hub de Notificação e o valor hubListenEndpoint pelo valor do ponto de extremidade encontrado na guia Políticas de Acesso, Serviço de Hub de Notificação do Azure, no Portal do Azure (veja a imagem abaixo).

    Inserir ponto de extremidade de política de Hubs de Notificação

  6. Agora adicione os métodos Start() e Awake() para inicializar a classe.

        /// <summary>
        /// Triggers before initialization
        /// </summary>
        void Awake()
        {
            // static instance of this class
            instance = this;
        }
    
        /// <summary>
        /// Use this for initialization
        /// </summary>
        void Start()
        {
            // Register the App at launch
            InitNotificationsAsync();
    
            // Begin listening for notifications
            StartCoroutine(WaitForNotification());
        }
    
  7. Adicione o método WaitForNotification para permitir que o aplicativo receba notificações da Biblioteca do Hub de Notificação sem entrar em conflito com o Thread Principal:

        /// <summary>
        /// This notification listener is necessary to avoid clashes 
        /// between the notification hub and the main thread   
        /// </summary>
        private IEnumerator WaitForNotification()
        {
            while (true)
            {
                // Checks for notifications each second
                yield return new WaitForSeconds(1f);
    
                if (notifReceived)
                {
                    // If a notification is arrived, moved the appropriate object to the new position
                    GameObject.Find(gameObjectName).transform.position = newObjPosition;
    
                    // Reset the flag
                    notifReceived = false;
                }
            }
        }
    
  8. O método a seguir, InitNotificationAsync(), registrará o aplicativo com o Serviço de Hub de notificação na inicialização. O código é comentado, pois o Unity não poderá compilar o projeto. Você removerá os comentários ao importar o pacote Nuget do Sistema de Mensagens do Azure no Visual Studio.

        /// <summary>
        /// Register this application to the Notification Hub Service
        /// </summary>
        private async void InitNotificationsAsync()
        {
            // PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
            // NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint);
    
            // Registration result = await hub.RegisterNativeAsync(channel.Uri);
    
            // If registration was successful, subscribe to Push Notifications
            // if (result.RegistrationId != null)
            // {
            //     Debug.Log($"Registration Successful: {result.RegistrationId}");
            //     channel.PushNotificationReceived += Channel_PushNotificationReceived;
            // }
        }
    
  9. O manipulador a seguir, Channel_PushNotificationReceived(), será acionado sempre que uma notificação for recebida. Ele desserializará a notificação, que será a Entidade de Tabela do Azure que foi movida no Aplicativo da Área de Trabalho e, em seguida, moverá o GameObject correspondente na cena do MR para a mesma posição.

    Importante

    O código é comentado porque o código faz referência à biblioteca de mensagens do Azure, que você adicionará depois de criar o projeto do Unity usando o Gerenciador de Pacotes Nuget, no Visual Studio. Dessa forma, o projeto Unity não poderá ser compilado, a menos que seja comentado. Lembre-se de que, se você criar seu projeto e desejar retornar ao Unity, precisará comentar novamente esse código.

        ///// <summary>
        ///// Handler called when a Push Notification is received
        ///// </summary>
        //private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)    
        //{
        //    Debug.Log("New Push Notification Received");
        //
        //    if (args.NotificationType == PushNotificationType.Raw)
        //    {
        //        //  Raw content of the Notification
        //        string jsonContent = args.RawNotification.Content;
        //
        //        // Deserialise the Raw content into an AzureTableEntity object
        //        AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent);
        //
        //        // The name of the Game Object to be moved
        //        gameObjectName = ate.RowKey;          
        //
        //        // The position where the Game Object has to be moved
        //        newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z);
        //
        //        // Flag thats a notification has been received
        //        notifReceived = true;
        //    }
        //}
    
  10. Lembre-se de salvar suas alterações antes de voltar para o Editor do Unity.

  11. Clique na Câmera principal no painel Hierarquia , para que suas propriedades apareçam no Inspetor.

  12. Com a pasta Scripts aberta, selecione o script NotificationReceiver e arraste-o para a Câmera principal. O resultado deve ser o seguinte:

    Arraste o script do receptor de notificação para a câmera

    Observação

    Se você estiver desenvolvendo isso para o Microsoft HoloLens, precisará atualizar o componente Câmera da Câmera Principal, para que:

    • Bandeiras claras: cor sólida
    • Em segundo plano: preto

Capítulo 16 – Criar o projeto de realidade misturada para UWP

Este capítulo é idêntico ao processo de compilação do projeto anterior. Tudo o que é necessário para a seção Unity deste projeto foi concluído, então é hora de construí-lo a partir do Unity.

  1. Navegue até Configurações de compilação ( Configurações de compilação de arquivo>).

  2. No menu Configurações de Build, verifique se Unity C# Projects* está marcado (o que permitirá que você edite os scripts neste projeto, após o build).

  3. Depois que isso for feito, clique em Compilar.

    Captura de tela que mostra a janela Configurações de construção com o botão 'Construir' destacado no canto inferior direito.

  4. Uma janela do Explorador de Arquivos aparecerá, solicitando um local para compilar. Crie uma nova pasta (clicando em Nova pasta no canto superior esquerdo) e nomeie-a como BUILDS.

    Criar pasta de compilações

    1. Abra a nova pasta BUILDS e crie outra pasta (usando Nova pasta mais uma vez) e nomeie-a NH_MR_App.

      criar NH_MR_Apps pasta

    2. Com o NH_MR_App selecionado. clique em Selecionar pasta. O projeto levará cerca de um minuto para ser construído.

  5. Após a compilação, uma janela do Explorador de Arquivos será aberta no local do seu novo projeto.

Capítulo 17 – Adicionar pacotes NuGet à solução UnityMRNotifHub

Aviso

Lembre-se de que, depois de adicionar os seguintes pacotes NuGet (e descomentar o código no próximo capítulo), o código, quando reaberto no projeto do Unity, apresentará erros. Se você quiser voltar e continuar editando no Editor do Unity, precisará comentar esse código de erro e, em seguida, descomentar novamente mais tarde, quando estiver de volta ao Visual Studio.

Depois que o build de realidade misturada for concluído, navegue até o projeto de realidade misturada, que você criou, e clique duas vezes no arquivo de solução (.sln) dentro dessa pasta para abrir sua solução com o Visual Studio 2017. Agora você precisará adicionar o pacote NuGet WindowsAzure.Messaging.managed ; essa é uma biblioteca usada para receber notificações do Hub de Notificação.

Para importar o pacote NuGet:

  1. No Gerenciador de Soluções, clique com o botão direito do mouse em sua Solução

  2. Clique em Gerenciar Pacotes NuGet.

    Abra o NuGet Manager

  3. Selecione a guia Procurar e pesquise WindowsAzure.Messaging.managed.

    Localizar o pacote de mensagens do Windows Azure

  4. Selecione o resultado (conforme mostrado abaixo) e, na janela à direita, marque a caixa de seleção ao lado de Projeto. Isso colocará uma marca na caixa de seleção ao lado de Project, juntamente com a caixa de seleção ao lado do projeto Assembly-CSharp e UnityMRNotifHub .

    Marque todos os projetos

  5. A versão inicialmente fornecida pode não ser compatível com este projeto. Portanto, clique no menu suspenso ao lado de Versão e clique em Versão 0.1.7.9 e clique em Instalar.

  6. Agora você concluiu a instalação do pacote NuGet. Encontre o código comentado que você inseriu na classe NotificationReceiver e remova os comentários.

Capítulo 18 – Editar aplicativo UnityMRNotifHub, classe NotificationReceiver

Depois de adicionar os pacotes NuGet, você precisará remover o comentário de parte do código dentro da classe NotificationReceiver .

Isso inclui:

  1. O namespace na parte superior:

    using Microsoft.WindowsAzure.Messaging;
    
  2. Todo o código dentro do método InitNotificationsAsync():

        /// <summary>
        /// Register this application to the Notification Hub Service
        /// </summary>
        private async void InitNotificationsAsync()
        {
            PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
            NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint);
    
            Registration result = await hub.RegisterNativeAsync(channel.Uri);
    
            // If registration was successful, subscribe to Push Notifications
            if (result.RegistrationId != null)
            {
                Debug.Log($"Registration Successful: {result.RegistrationId}");
                channel.PushNotificationReceived += Channel_PushNotificationReceived;
            }
        }
    

Aviso

O código acima contém um comentário: certifique-se de não ter descomentado acidentalmente esse comentário (pois o código não será compilado se você tiver!).

  1. E, por último, o Channel_PushNotificationReceived evento:

        /// <summary>
        /// Handler called when a Push Notification is received
        /// </summary>
        private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)
        {
            Debug.Log("New Push Notification Received");
    
            if (args.NotificationType == PushNotificationType.Raw)
            {
                //  Raw content of the Notification
                string jsonContent = args.RawNotification.Content;
    
                // Deserialize the Raw content into an AzureTableEntity object
                AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent);
    
                // The name of the Game Object to be moved
                gameObjectName = ate.RowKey;
    
                // The position where the Game Object has to be moved
                newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z);
    
                // Flag thats a notification has been received
                notifReceived = true;
            }
        }
    

Com estes não comentados, certifique-se de salvar e, em seguida, prossiga para o próximo capítulo.

Capítulo 19 – Associar o projeto de realidade misturada ao aplicativo Store

Agora você precisa associar o projeto de realidade misturada ao aplicativo da Store criado no início do laboratório.

  1. Abrir a solução.

  2. Clique com o botão direito do mouse no projeto do aplicativo UWP no painel Gerenciador de Soluções, vá para a Loja e Associe o Aplicativo à Loja....

    Associação de loja aberta

  3. Uma nova janela será exibida chamada Associar seu aplicativo à Windows Store. Clique em Avançar.

    Vá para a próxima tela

  4. Ele carregará todos os aplicativos associados à conta que você fez login. Se você não estiver conectado à sua conta, poderá fazer login nesta página.

  5. Localize o nome do aplicativo da loja que você criou no início deste tutorial e selecione-o. Em seguida, clique em Próximo.

    Encontre e selecione o nome da sua loja

  6. Clique em Associar.

    Associar o aplicativo

  7. Seu aplicativo agora está associado ao aplicativo da loja. Isso é necessário para habilitar as notificações.

Capítulo 20 – Implantar aplicativos UnityMRNotifHub e UnityDesktopNotifHub

Este capítulo pode ser mais fácil com duas pessoas, pois o resultado incluirá os dois aplicativos em execução, um em execução na área de trabalho do computador e o outro no fone de ouvido imersivo.

O aplicativo de headset imersivo está aguardando para receber alterações na cena (alterações de posição dos GameObjects locais) e o aplicativo da área de trabalho fará alterações em sua cena local (alterações de posição), que serão compartilhadas com o aplicativo MR. Faz sentido implantar o aplicativo MR primeiro, seguido pelo aplicativo Desktop, para que o receptor possa começar a ouvir.

Para implantar o aplicativo UnityMRNotifHub em seu computador local:

  1. Abra o arquivo de solução do aplicativo UnityMRNotifHub no Visual Studio 2017.

  2. Na Plataforma de Solução, selecione x86, Computador Local.

  3. Na Configuração da Solução, selecione Depurar.

    Captura de tela que mostra a Configuração da Solução definida como 'Depurar' na barra de ferramentas.

  4. Vá para o menu Compilar e clique em Implantar Solução para fazer o sideload do aplicativo em seu computador.

  5. Seu aplicativo agora deve aparecer na lista de aplicativos instalados, pronto para ser iniciado.

Para implantar o aplicativo UnityDesktopNotifHub no computador local:

  1. Abra o arquivo de solução do aplicativo UnityDesktopNotifHub no Visual Studio 2017.

  2. Na Plataforma de Solução, selecione x86, Computador Local.

  3. Na Configuração da Solução, selecione Depurar.

    Captura de tela que mostra a Configuração da Solução definida como 'Depurar'.

  4. Vá para o menu Compilar e clique em Implantar Solução para fazer o sideload do aplicativo em seu computador.

  5. Seu aplicativo agora deve aparecer na lista de aplicativos instalados, pronto para ser iniciado.

  6. Inicie o aplicativo de realidade misturada, seguido pelo aplicativo da área de trabalho.

Com ambos os aplicativos em execução, mova um objeto na cena da área de trabalho (usando o botão esquerdo do mouse). Essas alterações posicionais serão feitas localmente, serializadas e enviadas para o serviço de Aplicativo de Funções. O serviço de Aplicativo de Funções atualizará a Tabela junto com o Hub de Notificação. Depois de receber uma atualização, o Hub de Notificação enviará os dados atualizados diretamente para todos os aplicativos registrados (nesse caso, o aplicativo de headset imersivo), que desserializará os dados de entrada e aplicará os novos dados posicionais aos objetos locais, movendo-os na cena.

Você concluiu seu aplicativo de Hubs de Notificação do Azure

Parabéns, você criou um aplicativo de realidade misturada que aproveita o Serviço de Hubs de Notificação do Azure e permite a comunicação entre aplicativos.

produto final - fim

Exercícios de bônus

Exercício 1

Você pode descobrir como alterar a cor dos GameObjects e enviar essa notificação para outros aplicativos que visualizam a cena?

Exercício 2

Você pode adicionar movimento dos GameObjects ao seu aplicativo MR e ver a cena atualizada em seu aplicativo da área de trabalho?