Partilhar via


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


Nota

Os tutoriais da Academia de Realidade Mista foram projetados com HoloLens (1ª geração) e Headsets Imersivos de Realidade Mista em mente. Como tal, sentimos que é importante deixar estes tutoriais no lugar para desenvolvedores que ainda estão procurando orientação no desenvolvimento para esses dispositivos. Esses tutoriais não serão atualizados com os conjuntos de ferramentas ou interações mais recentes que estão sendo usados para o HoloLens 2. Eles serão mantidos para continuar trabalhando nos dispositivos suportados. Haverá uma nova série de tutoriais que serão publicados no futuro que demonstrarão como desenvolver para o HoloLens 2. Este aviso será atualizado com um link para esses tutoriais quando eles forem publicados.


produto final -start

Neste curso, você aprenderá como adicionar recursos de Hubs de Notificação a um aplicativo de realidade mista 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 aos programadores enviar notificações 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 o trabalho para a nuvem, em vez de seu aplicativo local, que pode ter muitos benefícios. O Azure Functions suporta 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 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

Tendo concluído este curso, você terá um aplicativo de fone de ouvido imersivo de realidade mista e um aplicativo de PC Desktop, que será capaz de 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. O movimento de objetos dentro do aplicativo para PC será enviado para a nuvem usando JSON, que será na forma de uma cadeia de caracteres, contendo um ID de objeto, tipo e informações de transformação (coordenadas X e Y).

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

  4. Ao receber uma notificação, que conterá o ID do objeto, digitar e transformar informações, o aplicativo de realidade mista aplicará as informações recebidas em sua própria cena.

Na sua aplicação, cabe-lhe a si decidir como irá integrar os resultados com o seu design. Este curso foi criado para ensiná-lo a integrar um Serviço do Azure ao seu Projeto Unity. É seu trabalho usar o conhecimento que você ganha com este curso para melhorar sua aplicação de realidade mista. Este curso é um tutorial independente, que não envolve diretamente nenhum outro Laboratório de Realidade Mista.

Suporte de dispositivos

Curso HoloLens Auriculares imersivos
MR e Azure 308: Notificações entre dispositivos ✔️ ✔️

Nota

Embora este curso se concentre principalmente em fones de ouvido imersivos (VR) do Windows Mixed Reality, você também pode aplicar o que aprendeu neste curso ao Microsoft HoloLens. À medida que você acompanha o curso, você verá anotações sobre quaisquer alterações que você possa precisar empregar para dar suporte ao HoloLens. Ao utilizar o HoloLens, poderá notar algum eco durante a captura de voz.

Pré-requisitos

Nota

Este tutorial foi projetado para desenvolvedores que têm experiência básica com Unity e C#. Por favor, esteja ciente de que os pré-requisitos e 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 software mais recente do que o listado abaixo.

Recomendamos o seguinte hardware e software para este curso:

Antes de começar

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

Capítulo 1 - Criar um aplicativo no Microsoft Developer Portal

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 Microsoft Developer Portal.

    Terá de iniciar sessão na sua Conta Microsoft.

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

    Criar um aplicativo

  3. Um pop-up aparecerá, em que você precisa reservar um nome para seu novo aplicativo. Na caixa de texto, insira um nome apropriado; Se o nome escolhido estiver disponível, aparecerá uma marca à 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.

    inverter um nome

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

Capítulo 2 - Recuperar as credenciais dos novos 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 Aplicativos.

    Portal de Registo de Candidaturas

    Aviso

    Terá de utilizar a sua Conta Microsoft para iniciar sessão.
    Esta tem de ser a Conta Microsoft que utilizou no Capítulo anterior, com o Portal do Programador da Loja Windows.

  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 na página de registro para encontrar sua 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 da aplicação

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

Com suas credenciais de 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.

    Nota

    Se ainda não tiver uma conta do Azure, terá de criar uma. Se você estiver seguindo este tutorial em uma situação de sala de aula ou laboratório, peça ajuda ao seu instrutor ou a um dos proctors 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

    Nota

    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. No canto inferior esquerdo deste prompt, selecione o botão Criar para criar uma associação com este 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 uma Localização.

    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 desejar 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 compreendeu 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 aparecerá no portal assim que a instância de serviço for criada.

    notificação

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

    Captura de ecrã que mostra o botão 'Ir para recurso' realçado 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.

    Copiar detalhes de segurança

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

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

  1. Se ainda não tiver sessão iniciada, inicie sessão no Portal do Azure.

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

    Nota

    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.

    Procurar conta de armazenamento

  4. A nova página fornecerá uma descrição do serviço de conta de armazenamento . No canto inferior esquerdo deste prompt, selecione o botão Criar para criar uma instância deste 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 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. No menu suspenso Replicação, selecione Armazenamento com redundância geográfica de acesso de leitura (RA-GRS).

    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 desejar ler mais sobre os Grupos de Recursos do Azure, siga este link sobre como gerenciar um Grupo de Recursos.

    10. Deixe as redes virtuais como Desativado se esta 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 aparecerá 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 recurso na notificação para explorar sua nova instância de serviço. Você será direcionado para a nova página de visão geral da instância do Serviço de Armazenamento.

    Captura de ecrã que mostra o botão 'Ir para o recurso' realçado na janela 'Implementação bem-sucedida'.

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

    Captura de ecrã 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. Este é o nome que você usará para se referir aos dados em seu aplicativo nos próximos capítulos. Insira um nome apropriado e clique em OK.

    Criar nova tabela

  12. Uma vez que a nova tabela tenha sido criada, você poderá vê-la na página de serviço 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 Table 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).

    Nota

    Se a Subscrição que utilizou para criar as suas Contas de Armazenamento não estiver visível, certifique-se de que tem:

    • Iniciou sessão na mesma conta que utilizou para o Portal do Azure.

    • Selecione a sua Subscrição na Página de Gestão de Conta (poderá ter de aplicar um filtro a partir das definições da sua conta):

      encontrar subscrição

  4. Seus serviços de nuvem do Azure serão exibidos. 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 estiver expandida, localize 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.

    abrir tabela de objetos de cena

  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. Será exibida uma janela solicitando que você adicione entidade. Você criará três entidades no total, cada uma com várias propriedades. Você notará que PartitionKey e RowKey já são fornecidos, pois eles são usados pela tabela para encontrar seus dados.

    partição e chave de linha

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

    adicionar valores corretos

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

  10. Clique em OK quando terminar.

    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 linha

  12. Crie uma propriedade adicional e, em seguida, 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 para esta entidade para 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 economizar.

Capítulo 6 - Criar um aplicativo de função do Azure

Crie um Aplicativo de Função do Azure, que será chamado pelo aplicativo de Á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 permitirá que sua Função do Azure carregue as bibliotecas necessárias.

  1. Abra o Bloco de Notas (prima a tecla Windows e escreva bloco de notas).

    Abrir o Bloco de Notas

  2. Com o bloco de notas aberto, insira a estrutura JSON abaixo nele. Depois de ter feito isso, salve-o em sua área de trabalho como project.json. É importante que a nomenclatura esteja correta: certifique-se de que NÃO tem uma extensão de arquivo .txt . Este 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. Inicie sessão no Portal do Azure.

  4. Depois de iniciar sessão, clique em Novo no canto superior esquerdo e procure por Function App, prima Enter.

    Procurar aplicação de função

    Nota

    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 Function App . No canto inferior esquerdo deste prompt, selecione o botão Criar para criar uma associação com este serviço.

    instância do aplicativo de função

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

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

    2. Selecione uma Subscrição.

    3. Selecione o nível de preço apropriado para você, se esta for a primeira vez que cria um Serviço de Aplicativo de Função, um nível gratuito deve 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 desejar 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, então 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 aparecerá 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 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 recurso' realçado.

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

    Adicionar nova função

  12. Dentro do 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, 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ções. Role para baixo para exibir os tipos roxos e clique no 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 por um elemento chamado HTTP PUT.

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

    1. Em 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 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 hiperlink Novo 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 êxito.

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

    Nota

    Usando as bibliotecas incluídas, a função recebe o nome e o local do objeto que foi movido na cena Unity (como um objeto C#, chamado UnityGameObject). Esse objeto é usado para atualizar os parâmetros do objeto dentro da 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.

    abrir painel de carregamento

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

  21. Navegue até o arquivo de project.json, que você criou no Bloco de Notas anteriormente, 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 dentro do editor de funções . Deve ter exatamente a mesma aparência da próxima imagem (abaixo do passo 23).

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

    função de integração

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

    abrir 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á construindo 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 você acabou de inserir podem não corresponder à sua tabela e detalhes de armazenamento e, portanto, precisará ser atualizado 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 Padrão, clique em Armazenamento de Tabela do Azure (tabela), em Entradas.

    Entradas de tabela

  29. Certifique-se de que o seguinte corresponde à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 seu 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ção.

      2. Você notará 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 à página abaixo, mostrando suas informações.

      entradas completas

  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: este é o nome da sua 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 aparecerá (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 Policy como DefaultFullSharedAccessSignature.

    6. Clique no botão Selecionar para voltar.

      Atualização de saída

  31. A página Saídas agora deve corresponder às 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 está funcionando. Para tal:

    1. Navegue até a página da função 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 da função, clique na guia Teste no lado direito da página para abrir a folha Teste :

      Captura de ecrã 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 no lugar, 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 as etapas acima exatamente, particularmente as configurações dentro do painel de integração.

Capítulo 7 - Configurar o projeto Desktop Unity

Importante

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

O seguinte é uma configuração típica para desenvolver com Unity e realidade mista e, como tal, é um bom modelo para outros projetos.

Configure e teste o seu auricular imersivo de realidade mista.

Nota

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

  1. Abra o Unity e clique em Novo.

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

  2. Você precisa fornecer um nome de projeto Unity, insira UnityDesktopNotifHub. Verifique se o tipo de projeto está definido como 3D. Defina o Local para algum lugar apropriado para você (lembre-se, mais perto de 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 Scripts 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, em seguida, clique no botão Alternar plataforma para aplicar sua seleção.

    Plataformas de comutação

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

    1. O Dispositivo de Destino está definido como Qualquer Dispositivo

      Esta Aplicação será para o seu ambiente de trabalho, por isso deve ser qualquer dispositivo

    2. O tipo de compilação está definido como D3D

    3. O SDK está definido como Instalado mais recente

    4. Versão do Visual Studio está definida como A versão mais recente instalada

    5. Build and Run está definido como Máquina Local

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

      1. Faça isso selecionando Adicionar cenas abertas. Será exibida uma janela de salvamento.

        Captura de ecrã que mostra a opção 'Adicionar cena aberta' realçada 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 Cenas.

        Captura de ecrã 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, no campo de texto Nome do arquivo:, digite NH_Desktop_Scene e pressione Salvar.

        Nova NH_Desktop_Scene

    7. As configurações restantes, em Configurações de compilação, 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 Scripting Runtime deve ser experimental (equivalente ao .NET 4.6)

      2. O back-end de scripts 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, verifique:

      • InternetClient

        Captura de tela que mostra o InternetClient selecionado em Recursos.

  8. De volta às configurações de compilação, o Unity C# Projects não está mais acinzentado, marque a caixa de seleção ao lado disso.

  9. Feche a janela Configurações de compilação.

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

    Importante

    Se você deseja pular o componente Unity set up para este projeto (Desktop App) e continuar direto no código, sinta-se à vontade para baixar este .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 por si só 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 - 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, certifique-se de ter baixado 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 Import Unity Package que aparece, você pode selecionar tudo em Plugin>Storage. 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
    • Sistema.Espacial

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

    Nota

    Estamos marcando esses plugins específicos para serem usados apenas no Editor Unity. Isso ocorre porque existem 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.

    Aplicar sem processamento

    Nota

    Estamos marcando este plugin "Não processar", porque o patcher de montagem Unity tem dificuldade em processar este plugin. O plugin ainda funcionará mesmo que não seja processado.

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

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

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

  • Lendo entidades dentro da 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 esquerdo para permitir que o usuário arraste objetos ao redor da cena.
  • Serializar os dados do objeto dessa cena Unity e enviá-los para o Aplicativo de Função do Azure.

Para criar esta classe:

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

    criar pasta de scripts

    criar scripts pasta 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'.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 -- ";
    

    Nota

    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 (consulte a imagem abaixo).

    buscar a chave da 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. Dentro da classe TableToScene , adicione o método que recuperará os valores da Tabela do Azure e os usará para gerar as primitivas apropriadas 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 da 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 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 de script TableToScene e arraste-o para a câmera principal. O resultado deve ser o seguinte:

    Adicionar script à câmara principal

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

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

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

  • Serializar os dados do objeto dessa cena Unity e enviá-los para o Aplicativo de Função 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ção do Azure encontrada no Serviço de Aplicativo de Função 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. Dentro do método Update(), adicione o código a seguir que detetará a entrada e o arrasto do mouse, 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 Aplicativo de Função do Azure, que atualizará a tabela do Azure e acionará 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(), como 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 do 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 Cloud Script para a câmera principal

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

Tudo o que era necessário para a secção Unidade 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 ecrã que mostra a janela Build Settings com a Plataforma Universal do Windows selecionada e o botão 'Build' realçado no canto inferior direito.

  3. Uma janela do 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 compilação

    1. Abra a nova pasta BUILDS e crie outra pasta (usando New Folder 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 o local do seu novo projeto. Não há necessidade de abri-lo, pois você precisa criar o outro projeto Unity primeiro, nos próximos capítulos.

Capítulo 12 - Configurar o Projeto de Unidade de Realidade Mista

O seguinte é uma configuração típica para desenvolver com a realidade mista 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 Unity com 'Novo' realçado no canto superior direito.

  2. Agora você precisará fornecer um nome de Projeto Unity, insira UnityMRNotifHub. Verifique se o tipo de projeto está definido como 3D. Defina o Local para algum lugar apropriado para você (lembre-se, mais perto de 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 Scripts Externo para Visual Studio 2017. Feche a janela Preferências .

    definir editor externo para VS

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

    alternar plataformas para UWP

  5. Vá para Configurações de compilação de arquivo>e certifique-se de que:

    1. O Dispositivo de Destino está definido como Qualquer Dispositivo

      Para o Microsoft HoloLens, defina Target Device como HoloLens.

    2. O tipo de compilação está definido como D3D

    3. O SDK está definido como Instalado mais recente

    4. Versão do Visual Studio está definida como A versão mais recente instalada

    5. Build and Run está definido como Máquina Local

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

      1. Faça isso selecionando Adicionar cenas abertas. Será exibida uma janela de salvamento.

        Captura de tela que mostra a janela Configurações de compilação com o botão 'Adicionar cenas abertas' realçado 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 Cenas.

        Captura de ecrã que mostra 'Nova pasta' realçada no canto superior esquerdo da janela Guardar 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 compilação, 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.

    Abrir as Definições do Media Player

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

    1. Na guia Outras configurações:

      1. A versão do Scripting Runtime deve ser experimental (equivalente ao .NET 4.6)

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

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

        Compatibilidade com API

    2. Mais abaixo no painel, em Configurações XR (encontradas abaixo de Configurações de publicação), marque Realidade Virtual Suportada, verifique se o SDK de Realidade Mista do Windows foi adicionado

      Atualizar configurações XR

    3. Na guia Configurações de publicação , em Recursos, verifique:

      • InternetClient

        Captura de ecrã que mostra o separador Definições de Publicação com InternetClient marcado.

  8. De volta às Configurações de compilação, o Unity C# Projects não está mais acinzentado: 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ê deseja pular o componente Unity set para este projeto (aplicativo de realidade mista) e continuar direto no código, sinta-se à vontade para baixar este .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 Mixed Reality Unity

Você usará a biblioteca do Armazenamento do Azure para Unity (que usa o SDK .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 - 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, certifique-se de ter baixado o .unitypackage mais recente. Em seguida, faça o seguinte:

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

  2. Na caixa Import Unity Package que aparece, você pode selecionar tudo em Plugin>Storage.

    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
    • Sistema.Espacial

    selecionar plugins

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

    Aplicar alterações na plataforma

    Nota

    Você está marcando esses plugins específicos para serem usados apenas no Editor Unity. Isso ocorre porque existem 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

      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

    Nota

    Você está marcando este plugin "Não processar" porque o patcher de montagem Unity tem dificuldade em processar este plugin. O plugin ainda funcionará mesmo que não seja processado.

Capítulo 14 - Criando a classe TableToScene no projeto Unity de realidade mista

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

Depois de concluir este Capítulo, ambos os seus Projetos Unity terão essa classe configurada na Câmera Principal.

Capítulo 15 - Criando a classe NotificationReceiver no projeto Mixed Reality Unity

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

  • Registrar o aplicativo no Hub de Notificação na inicialização.
  • Ouvir notificações provenientes do Hub de Notificações.
  • Desserialização dos dados do objeto das 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 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 da política dos 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 como Unity não será capaz de construir o projeto. Você removerá os comentários quando 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á 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 de Área de Trabalho e, em seguida, moverá o GameObject correspondente na cena 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 Unity usando o Gerenciador de Pacotes Nuget, dentro do Visual Studio. Como tal, o projeto Unity não será capaz de construir, a menos que seja comentado. Esteja ciente de que, se você construir seu projeto e, em seguida, desejar retornar ao Unity, você 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 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 recetor de notificação para a câmera

    Nota

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

    • Bandeiras claras: cor sólida
    • Fundo: Preto

Capítulo 16 - Construir o projeto de realidade mista para UWP

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

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

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

  3. Depois disso, clique em Compilar.

    Captura de ecrã que mostra a janela Build Settings com o botão 'Build' realçado no canto inferior direito.

  4. Uma janela do 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 compilações

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

      Criar pasta NH_MR_Apps

    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 dentro do Projeto Unity, apresentará erros. Se você deseja voltar e continuar editando no Editor Unity, você precisará comentar esse código incorreto e, em seguida, descomentar novamente mais tarde, quando estiver de volta ao Visual Studio.

Depois que a compilação de realidade mista tiver sido concluída, navegue até o projeto de realidade mista, 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 , que é 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 do NuGet

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

    Localizar o pacote de mensagens do Windows Azure

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

    assinalar 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, em seguida, 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á descomentar parte do código dentro da classe NotificationReceiver .

O que está incluído:

  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: certifique-se de que você não acidentalmente descomentou esse comentário (como 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 que guarda e, em seguida, prossiga para o próximo Capítulo.

Capítulo 19 - Associar o projeto de realidade mista ao aplicativo da Loja

Agora você precisa associar o projeto de realidade mista ao aplicativo da Store que 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 Loja e Associe Aplicativo à Loja....

    Associação Loja Aberta

  3. Será exibida uma nova janela chamada Associar seu aplicativo à Windows Store. Clique em Next.

    ir para a próxima tela

  4. Irá carregar todas as Aplicações associadas à Conta em que iniciou sessão. Se não tiver sessão iniciada na sua conta, pode iniciar sessão nesta página.

  5. Encontre o nome do aplicativo da Loja que você criou no início deste tutorial e selecione-o. Clique depois em Seguinte.

    Encontre e selecione o nome da sua loja

  6. Clique em Associar.

    associar o aplicativo

  7. A sua Aplicação está agora Associada à Aplicação 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á ambos os aplicativos em execução, um em execução na área de trabalho do computador e o outro dentro do fone de ouvido imersivo.

O aplicativo de fone de ouvido imersivo está esperando para receber alterações na cena (mudanças de posição do GameObjects local), e o aplicativo de área de trabalho fará alterações em sua cena local (alterações de posição), que serão compartilhadas no aplicativo MR. Faz sentido implantar o aplicativo MR primeiro, seguido pelo aplicativo Desktop, para que o recetor possa começar a ouvir.

Para implantar o aplicativo UnityMRNotifHub em sua máquina local:

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

  2. Na Plataforma de Solução, selecione x86, Máquina Local.

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

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

  4. Vá para o menu Build e clique em Deploy Solution para fazer sideload do aplicativo para sua máquina.

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

Para implantar o aplicativo UnityDesktopNotifHub na máquina local:

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

  2. Na Plataforma de Solução, selecione x86, Máquina Local.

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

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

  4. Vá para o menu Build e clique em Deploy Solution para fazer sideload do aplicativo para sua máquina.

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

  6. Inicie a aplicação de realidade mista, seguida da aplicação 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ção. O serviço Aplicativo de Função atualizará a Tabela junto com o Hub de Notificação. Tendo recebido uma atualização, o Hub de Notificação enviará os dados atualizados diretamente para todos os aplicativos registrados (neste caso, o aplicativo de fone de ouvido imersivo), que desserializará os dados recebidos e aplicará os novos dados posicionais aos objetos locais, movendo-os em cena.

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

Parabéns, você criou um aplicativo de realidade mista 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 do GameObjects e enviar essa notificação para outros aplicativos que visualizam a cena?

Exercício 2

Você pode adicionar o movimento do GameObjects ao seu aplicativo MR e ver a cena atualizada em seu aplicativo de desktop?