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 HoloLens 2. Este aviso será atualizado com um link para esses tutoriais quando eles forem postados.


final product -start

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, todas alimentadas 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áginaHubs de Notificação do Azure.

Azure Functions é um serviço da Microsoft, que permite que os desenvolvedores executem pequenas partes de código, 'functions', no Azure. Isso fornece uma maneira de delegar o trabalho para a nuvem, em vez de seu aplicativo local, que pode ter muitos benefícios. 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 Azure Functions.

O Azure Tables é um serviço de nuvem da Microsoft, que permite que os desenvolvedores armazenem dados não SQL estruturados 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áginaTabelas do Azure

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

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

  2. A movimentação de objetos dentro do aplicativo pc será enviada para a nuvem usando JSON, que estará na forma de uma cadeia de caracteres, contendo uma ID de objeto, um 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 a movimentação de objetos do serviço Hubs de Notificação (que acabou de ser atualizado pelo aplicativo 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 seu aplicativo, cabe a você saber como você integrará os resultados ao seu design. Este curso foi projetado para ensinar como integrar um Serviço do Azure ao seu Projeto do Unity. É seu trabalho usar o conhecimento obtido com este curso para aprimorar seu aplicativo de realidade misturada. Este curso é um tutorial independente, que não envolve diretamente nenhum outro Realidade Misturada Labs.

Suporte a dispositivos

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

Observação

Embora este curso se concentre principalmente em Windows Mixed Reality headsets imersivos (VR), você também pode aplicar o que aprende neste curso a 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 projetado para desenvolvedores que têm experiência básica com Unity e C#. Lembre-se também de que os pré-requisitos e as instruções escritas neste documento representam o que foi testado e verificado no momento da gravação (maio de 2018). Você é livre para usar o software mais recente, conforme listado no artigo instalar as ferramentas , embora não se presuma que as informações neste curso corresponderão perfeitamente ao que você encontrará no software mais recente do que o listado abaixo.

Recomendamos o seguinte hardware e software para este curso:

Antes de começar

  • Para evitar problemas ao criar esse projeto, é altamente sugerido que você crie o projeto mencionado neste tutorial em uma pasta raiz ou quase raiz (caminhos de pasta longa podem causar problemas no tempo de build).
  • 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 ele possa enviar e receber notificações.

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

    Você precisará fazer logon em sua conta microsoft.

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

    criar um aplicativo

  3. Um pop-up será exibido, no qual você precisará reservar um nome para seu novo aplicativo. Na caixa de texto, insira um nome apropriado; se o nome escolhido estiver disponível, um tique aparecerá à direita da caixa de texto. Depois de inserir um nome disponível, clique no botão Reservar nome do produto na parte inferior esquerda do pop-up.

    inverter 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 Aplicativo, 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 Aplicativo.

    portal de registro de aplicativos

    Aviso

    Você precisará usar sua conta microsoft para fazer logon.
    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 para uma nova página que tem o nome do aplicativo mais Registro.

    seu aplicativo recém-registrado

  3. Role para baixo a página de registro para encontrar a seção Segredos do Aplicativo e o SID do Pacote para 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á ir para 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 situação de sala de aula ou laboratório, peça ajuda ao instrutor ou a um dos supervisores para configurar sua nova conta.

  2. Depois de fazer logon, clique em Novo no canto superior esquerdo, pesquise Hub de Notificação e clique em Inserir.

    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 deste 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 esse Serviço.

    7. Selecione Criar.

      preencher detalhes do serviço

  5. Depois de clicar em Criar, você precisará aguardar a criação do serviço, isso pode levar um minuto.

  6. Uma notificação será exibida no portal depois 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

  8. Na página de visão geral, no meio da página, clique em Windows (WNS). O painel à direita será alterado 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.

    copiar os detalhes de segurança

Capítulo 4 – Configurar o Portal do Azure: criar o Serviço de 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. Depois de fazer logon, clique em Novo no canto superior esquerdo, pesquise Conta de armazenamento e clique em Inserir.

    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 conta de armazenamento . Na parte inferior esquerda deste 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 será exibido:

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

    2. Para 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 de acesso de leitura).

    6. Para Desempenho, clique em Padrão.

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

    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.

      preencher detalhes de armazenamento

  6. Depois de clicar em Criar, você precisará aguardar a criação do serviço, isso pode levar um minuto.

  7. Uma notificação será exibida no portal depois 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 sua nova página de visão geral da instância do Serviço de Armazenamento.

    Captura de tela que mostra o botão

  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 será alterado 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ê precisará 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 por meio do Visual Studio.

  1. Abra o Visual Studio.

  2. No menu, clique em Exibir>Explorer na Nuvem.

    open 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 Conta (talvez seja necessário aplicar um filtro das configurações de sua conta):

      localizar assinatura

  4. Seus serviços de nuvem do Azure serão mostrados. Localize 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 armazenamento e, depois de expandida, localize Tabelas e clique na seta ao lado disso para revelar a Tabela que você criou no último Capítulo. Clique duas vezes em sua Tabela.

    tabela de objetos de cena aberta

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

    adicionar nova tabela

  7. Uma janela será exibida 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á foram fornecidos, pois eles 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 que você adicionar, embora incremente a RowKey todas as vezes):

    adicionar valores corretos

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

  10. Clique em OK quando terminar.

    clique em ok quando terminar

    Aviso

    Verifique se você alterou o Tipo das entradas X, Y e Z para Double.

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

    primeira linha

  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 para os mostrados abaixo.

    adicionar cilindro

  14. Sua tabela agora deve ser semelhante à mostrada abaixo.

    tabela concluída

  15. Você concluiu 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 desktop 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 permitirá 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).

    abrir o bloco de notas

  2. Com o Bloco de Notas aberto, insira a estrutura JSON abaixo nela. Depois de fazer isso, salve-o em sua área de trabalho como project.json. É importante que a nomenclatura esteja correta: verifique se ela NÃO tem 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 logon, clique em Novo no canto superior esquerdo e pesquise Aplicativo de Funções, pressione Enter.

    pesquisar 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. Para 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 criar um Serviço de Aplicativo de Função, 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 o sistema operacional, 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 que o armazenamento criado 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, fique à vontade para deixá-lo desativado.

    10. Clique em Criar.

      criar nova instância

  7. Depois de clicar em Criar , você terá que aguardar a criação do serviço, isso pode levar um minuto.

  8. Uma notificação será exibida no portal depois 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

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

    adicionar nova função

  12. No painel central, a janela Criação de função será exibida. Ignore as informações na metade superior do painel e clique em Função personalizada, que está localizada perto da parte inferior (na área azul, como 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 no elemento HTTP PUT .

    http put link

    Importante

    Talvez seja necessário rolar mais para baixo na página (e essa imagem pode não ser 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 será exibida, na qual você precisará configurar a função (veja abaixo a imagem).

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

    2. Em 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 o mesmo caso de letra).

    5. Na seção Conexão da conta de armazenamento, use o menu suspenso e selecione sua conta de armazenamento nela. Se ele não estiver lá, clique no hiperlink Novo junto com o título da seção para mostrar outro painel, em que sua conta de armazenamento deve ser listada.

      Captura de tela que mostra a seção 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 êxito.

    função create

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

    atualizar código de 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). Em seguida, esse objeto é usado para atualizar os parâmetros de objeto dentro da tabela criada. Depois disso, a função faz uma chamada para o serviço do Hub de Notificação criado, que notifica todos os aplicativos assinados.

  18. Com o código em vigor, clique em Salvar.

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

    abrir o painel de upload

  20. Um painel deslizará da direita para dentro. Nesse painel, clique em Carregar e um Navegador de Arquivos será exibido.

  21. Navegue até e clique no arquivo project.json que você criou anteriormente no Bloco de Notas 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 abrirá-o no editor de funções . Ele deve ter exatamente a mesma aparência da próxima imagem (abaixo da etapa 23).

  23. Em seguida, no painel à esquerda, abaixo do Functions, clique no link Integrar .

    Função integrate

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

    abrir o editor avançado

  25. Um arquivo function.json será aberto no painel central, que precisa ser substituído pelo snippet de código a seguir. 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 para o editor padrão

  27. Você pode observar que os parâmetros de entrada que você 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. Verifique se o seguinte corresponde às suas informações, pois elas podem ser diferentes (há uma imagem abaixo das seguintes etapas):

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

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

      Captura de tela que mostra a janela Conta de Armazenamento com 'Criar novo' realçada 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 da conexão da Conta de Armazenamento foi criado.

      3. Pressione Salvar quando terminar.

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

      entradas concluídas

  30. Em seguida, clique em Hub de Notificação do Azure (notificação) – em Saídas. Verifique se as informações a seguir correspondem, pois elas podem ser diferentes (há uma imagem abaixo das seguintes etapas):

    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 junto com o menu suspenso.

      saídas marcar

    3. O pop-up Conexão será exibido (veja a imagem abaixo), em que 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 ao abaixo, mas com suas informações. Pressione 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ções mais uma vez:

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

    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' realçado 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 na parte inferior direita e o teste será executado. Os logs de saída do teste serão exibidos 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á dobrar marcar que seguiu exatamente as etapas acima, especialmente as configurações dentro do painel de integração.

Capítulo 7 – Configurar o Projeto do Unity da Área de Trabalho

Importante

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

Veja a seguir uma configuração típica para o desenvolvimento com o Unity e a 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 exigirá 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

  2. Você precisa fornecer um nome de Projeto do Unity, inserir UnityDesktopNotifHub. Verifique se o tipo de projeto está definido como 3D. Defina o Local como um lugar apropriado para você (lembre-se, mais próximo 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, em seguida, na nova janela, navegue até Ferramentas Externas. Altere o Editor de Script Externo para o Visual Studio 2017. Feche a janela Preferências.

    definir ferramentas vs externas

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

    alternar plataformas

  5. Enquanto ainda estiver emConfigurações de Build de Arquivo>, verifique se:

    1. O dispositivo de destino é definido como Qualquer Dispositivo

      Este aplicativo será para sua área de trabalho, portanto, deve ser Qualquer Dispositivo

    2. O Tipo de Build é definido como D3D

    3. O SDK está definido como Mais recente instalado

    4. A versão do Visual Studio está definida como Mais Recente instalada

    5. Compilar e Executar é definido como Computador Local

    6. Enquanto estiver aqui, vale a pena salvar a cena e adicioná-la ao build.

      1. Faça isso selecionando Adicionar Cenas Abertas. Uma janela de salvamento será exibida.

        Captura de tela que mostra a 'Adicionar Cena Aberta' realçada no canto superior direito.

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

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

      3. Abra a pasta Cenas recém-criada e, em seguida, no campo Nome do arquivo : texto, 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 em que o Inspetor está localizado.

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

    1. Na guia Outras Configurações :

      1. A versão de runtime 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

        Versão 4.6 net

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

      • InternetClient

        Captura de tela que mostra InternetClient selecionado em Recursos.

  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. Feche a janela Configurações de Build.

  10. Salve a cena e acena de salvamentodo arquivo> de projeto/projeto de salvamento de arquivo>.

    Importante

    Se você quiser ignorar o componente Configurar do Unity para este projeto (Aplicativo da Área de Trabalho) e continuar diretamente no código, fique à vontade para baixar esse .unitypackage, importá-lo para seu projeto como um Pacote Personalizado e, em seguida, continuar a partir 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 pacote .unity ao Unity usando a opção de menu Pacote Personalizado importar pacote > de ativos>.

  2. Na caixa Importar Pacote do Unity que aparece, você pode selecionar tudo em >Armazenamento de Plug-in. 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 exibição Projeto e selecione apenas os seguintes plug-ins:

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

desmarcar Qualquer plataforma

  1. Com esses plug-ins específicos selecionados, desmarqueQualquer Plataforma e desmarqueo WSAPlayer e clique em Aplicar.

    aplicar dlls de plataforma

    Observação

    Estamos marcando esses plug-ins específicos para serem usados apenas no Editor do Unity. Isso ocorre porque há diferentes versões 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

      set não processam 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 esse plug-in "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 Unity da Área de Trabalho

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

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

  • Entidades de leitura dentro da Tabela do Azure.
  • Usando os dados de Tabela, determine quais objetos gerar e em qual posição.

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

  • Registrando o evento de clique à esquerda, para permitir que o usuário arraste objetos ao redor da cena.
  • Serializando os dados do objeto desta cena do Unity e enviando-os 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 de Projeto, Criar>Pasta. Nomeie a pasta Scripts.

    criar pasta de scripts

    criar scripts pasta 2

  2. Clique duas vezes na pasta que acabou de ser criada para abri-la.

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

    Captura de tela que mostra como criar o novo script 'TableToScene'.Renomear 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 pelo valor accountKey pelo valor de chave encontrado no Serviço de Armazenamento do Azure, no Portal do Azure (consulte 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 os usará 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 do 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 main

Capítulo 10 – Criar a classe CloudScene no Projeto do Unity da Área de Trabalho

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

  • Registrando o evento de clique à esquerda, para permitir que o usuário arraste objetos ao redor da cena.

  • Serializando os dados do objeto desta cena do Unity e enviando-os para o Aplicativo de Funções do Azure.

Para criar o segundo script:

  1. Clique com o botão direito do mouse na pasta Scripts , clique em Criar, Script em C#. Nomear 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 Azure Function Serviço de Aplicativo, 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. Dentro do 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 removido um objeto, ele passará o nome e as coordenadas do objeto para o método UpdateCloudScene(), que chamará o serviço aplicativo de funções do Azure, 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. Salvar o código e retornar ao Unity

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

    1. Clique na Câmera Principal do 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:

      arrastar o script de nuvem para main câmera

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

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

  1. Navegue até Configurações de Build (Configurações de Build de Arquivo>).

  2. Na janela Configurações de Build , clique em Compilar.

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

  3. Uma janela Explorador de Arquivos será exibida, 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.

      NH_Desktop_App de nome da pasta

    2. Com o NH_Desktop_App selecionado. clique em Selecionar Pasta. O projeto levará um minuto ou mais para ser compilado.

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

Capítulo 12 – Configurar Realidade Misturada Projeto do Unity

Veja a seguir uma configuração típica para desenvolver 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' realçado no canto superior direito.

  2. Agora você precisará fornecer um nome de Projeto do Unity, inserir UnityMRNotifHub. Verifique se o tipo de projeto está definido como 3D. Defina o Local como um lugar apropriado para você (lembre-se, mais próximo 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, em seguida, na nova janela, navegue até Ferramentas Externas. Altere o Editor de Script Externo para o Visual Studio 2017. Feche a janela Preferências.

    definir o editor externo como VS

  4. Em seguida, vá paraConfiguraçõ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á paraConfigurações de Build de Arquivo> e verifique se:

    1. O dispositivo de destino é definido como Qualquer Dispositivo

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

    2. O Tipo de Build é definido como D3D

    3. O SDK está definido como Mais recente instalado

    4. A versão do Visual Studio está definida como Mais Recente instalada

    5. Compilar e Executar é definido como Computador Local

    6. Enquanto estiver aqui, vale a pena salvar a cena e adicioná-la ao build.

      1. Faça isso selecionando Adicionar Cenas Abertas. Uma janela de salvamento será exibida.

        Captura de tela que mostra a janela Configurações de Build com o botão

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

        Captura de tela que mostra 'Nova pasta' realçada no canto superior esquerdo na janela Salvar Cena.

      3. Abra a pasta Cenas recém-criada e, em seguida, no campo Nome do arquivo : texto, 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 em que o Inspetor está localizado.

    abrir configurações do player

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

    1. Na guia Outras Configurações :

      1. A versão de runtime 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 de XR (encontradas abaixo de Configurações de Publicação), marque Com suporte à Realidade Virtual, verifique se o SDK do Windows Mixed Reality foi adicionado

      atualizar configurações do xr

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

      • 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 Build.

  10. Salve a cena e acena de salvamentodo arquivo> de projeto/projeto de salvamento de arquivo>.

    Importante

    Se você quiser ignorar o componente de Configuração do Unity para este projeto (aplicativo de realidade misturada) e continuar diretamente no código, fique à vontade para baixar esse .unitypackage, importá-lo para seu projeto como um Pacote Personalizado e, em seguida, continuar a partir do Capítulo 14. Você ainda precisará adicionar os componentes de script.

Capítulo 13 – Importando as DLLs no projeto do Realidade Misturada Unity

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 pacote .unity mais recente. Em seguida, faça o seguinte:

  1. Adicione o pacote .unity que você baixou acima ao Unity usando a opção de menuPacote Personalizadodo Pacote> de Importação de Ativos>.

  2. Na caixa Importar Pacote do Unity que aparece, você pode selecionar tudo em >Armazenamento de Plug-in.

    importar pacote

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

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

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

    selecionar plug-ins

  5. Com esses plug-ins específicos selecionados, desmarqueQualquer Plataforma e desmarqueo 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á diferentes versões 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

      selecionar cliente de serviços de dados

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

    não processar

    Observação

    Você está marcando esse plug-in "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 do 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 projetos do Unity terão essa classe configurada na Câmera Principal.

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

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

  • Registrar o aplicativo com o Hub de Notificação na inicialização.
  • Escutando as notificações provenientes do Hub de Notificação.
  • Desserializando os 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 na pasta Scripts , clique em Criar, Script em C#. Nomeie o script NotificationReceiver.

    create new c# scriptname it 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 do Hub de Notificação e pelo valor hubListenEndpoint pelo valor do ponto de extremidade encontrado na guia Políticas de Acesso, Serviço do 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 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 Azure Messaging 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á disparado 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 do Unity não poderá ser compilado, a menos que seja comentado. Lembre-se de que, se você criar seu projeto e, em seguida, 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 do 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:

    arrastar 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:

    • Sinalizadores Claros: 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 build do projeto anterior. Tudo o que é necessário para a seção unity deste projeto foi concluído, portanto, é hora de compilá-lo do Unity.

  1. Navegue até Configurações de Build (Configurações de Build deArquivo> ).

  2. No menu Configurações de Build, verifique se o 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 Build com o botão

  4. Uma janela Explorador de Arquivos será exibida, 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 builds

    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á um minuto ou mais para ser compilado.

  5. Após o build, uma janela Explorador de Arquivos será aberta no local do novo projeto.

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

Aviso

Lembre-se de que, depois de adicionar os seguintes Pacotes NuGet (e cancelar o comentário do código no próximo Capítulo), o Código, quando reaberto no Projeto do Unity, apresentará erros. Se você quiser voltar e continuar a edição no Editor do Unity, precisará comentar esse código incorreto e, em seguida, cancelar o comentário novamente mais tarde, depois de voltar 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) nessa 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.

    abrir o gerenciador de nuget

  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á um tique na caixa de seleção ao lado do Project, juntamente com a caixa de seleção ao lado do projeto Assembly-CSharp e UnityMRNotifHub .

    marcar todos os projetos

  5. A versão fornecida inicialmente 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. Você terminou de instalar o pacote NuGet. Localize o código comentado inserido na classe NotificationReceiver e remova os comentários..

Capítulo 18 – Editar aplicativo UnityMRNotifHub, classe NotificationReceiver

Após ter adicionado os Pacotes NuGet, você precisará descompactar 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 tem um comentário: verifique se você não descompactou acidentalmente esse comentário (pois o código não será compilado se você tiver!).

  1. E, por fim, o evento Channel_PushNotificationReceived :

        /// <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 eles descompactado, 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 da Store

Agora você precisa associar o projeto de realidade misturada ao Aplicativo da Loja no qual você criou no início do laboratório.

  1. Abra 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 Store e Associe o Aplicativo à Loja....

    abrir associação de repositório

  3. Uma nova janela será exibida chamada Associar seu aplicativo à Windows Store. Clique em Próximo.

    ir para a próxima tela

  4. Ele carregará todos os Aplicativos associados à Conta que você fez logon. Se você não estiver conectado à sua conta, poderá fazer logon 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.

    localizar e selecionar o nome da loja

  6. Clique em Associar.

    associar o aplicativo

  7. Seu aplicativo agora está associado ao aplicativo da Loja. Isso é necessário para habilitar 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á aplicativos em execução, um em execução no computador Desktop e outro dentro do headset imersivo.

O aplicativo de headset imersivo está aguardando para receber alterações na cena (alterações de posição do GameObjects local) e o aplicativo Desktop 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 no 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 sideload do aplicativo no computador.

  5. Seu aplicativo agora deve aparecer na lista de aplicativos instalados, prontos para serem iniciados.

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 sideload do aplicativo no computador.

  5. Seu aplicativo agora deve aparecer na lista de aplicativos instalados, prontos para serem iniciados.

  6. Inicie o aplicativo de realidade misturada, seguido pelo aplicativo Desktop.

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 aplicativo de funções. Em seguida, o serviço 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 para a cena.

Seu aplicativo de Hubs de Notificação do Azure concluído

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.

final product -end

Exercícios de bônus

Exercício 1

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

Exercício 2

Você pode adicionar a movimentação do GameObjects ao seu aplicativo mr e ver a cena atualizada em seu aplicativo da área de trabalho?