Noções básicas do HoloLens (1ª geração) 101E: Concluir projeto com emulador

Importante

Os tutoriais do Realidade Misturada Academy foram projetados com o HoloLens (1ª geração), o Unity 2017 e Realidade Misturada headsets imersivos 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 ou interações mais recentes sendo usados para HoloLens 2 e podem não ser compatíveis com versões mais recentes do Unity. Eles serão mantidos para continuar funcionando nos dispositivos compatíveis. Uma nova série de tutoriais foi postada para o HoloLens 2.


Este tutorial orientará você por um projeto completo, criado no Unity, que demonstra os principais recursos de Windows Mixed Reality no HoloLens, incluindo foco, gestos, entrada de voz, som espacial e mapeamento espacial. O tutorial levará aproximadamente 1 hora para ser concluído.

Suporte a dispositivos

Curso HoloLens Headsets imersivos
Noções básicas do MR 101E: projeto completo com emulador ✔️

Antes de começar

Pré-requisitos

Arquivos de projeto

  • Baixe os arquivos necessários para o projeto. Requer o Unity 2017.2 ou posterior.
    • Se você ainda precisar de suporte do Unity 5.6, use esta versão.
    • Se você ainda precisar de suporte do Unity 5.5, use esta versão.
    • Se você ainda precisar de suporte do Unity 5.4, use esta versão.
  • Cancele o arquivamento dos arquivos na área de trabalho ou em outro local de fácil acesso. Mantenha o nome da pasta como Origami.

Observação

Se você quiser examinar o código-fonte antes de baixar, ele estará disponível no GitHub.

Capítulo 1 – Mundo "Holo"

Neste capítulo, configuraremos nosso primeiro projeto do Unity e percorreremos o processo de build e implantação.

Objetivos

  • Configure o Unity para desenvolvimento holográfico.
  • Crie um holograma.
  • Veja um holograma que você fez.

Instruções

  • Inicie o Unity.
  • Selecione Abrir.
  • Insira o local como a pasta Origami que você não arquivou anteriormente.
  • Selecione Origami e clique em Selecionar Pasta.
  • Salve a nova cena: Arquivo / Salvar Cena Como.
  • Nomeie a cena Origami e pressione o botão Salvar .

Configurar a câmera main

  • No Painel de Hierarquia, selecione Câmera Principal.
  • No Inspetor , defina sua posição de transformação como 0,0,0.
  • Localize a propriedade Limpar Sinalizadores e altere a lista suspensa de Skybox para Cor sólida.
  • Clique no campo Tela de fundo para abrir um seletor de cor.
  • Defina R, G, B e A para 0.

Configurar a cena

  • No Painel de Hierarquia, clique em Criar e Criar Vazio.
  • Clique com o botão direito do mouse no novo GameObject e selecione Renomear. Renomeie GameObject para OrigamiCollection.
  • Na pasta Hologramas no Painel de Projeto:
    • Arraste Stage para a Hierarquia para ser um filho de OrigamiCollection.
    • Arraste Sphere1 para a Hierarquia para ser um filho de OrigamiCollection.
    • Arraste Sphere2 para a Hierarquia para ser um filho de OrigamiCollection.
  • Clique com o botão direito do mouse no objeto Luz Direcional no Painel de Hierarquia e selecione Excluir.
  • Na pasta Hologramas, arrasteLuzes para a raiz do Painel de Hierarquia.
  • Na Hierarquia, selecione OrigamiCollection.
  • No Inspetor, defina a posição de transformação como 0, -0.5, 2.0.
  • Pressione o botão Reproduzir no Unity para visualizar os hologramas.
  • Você deve ver os objetos Origami na janela de visualização.
  • Pressione Reproduzir uma segunda vez para interromper o modo de visualização.

Exportar o projeto do Unity para o Visual Studio

  • No Unity, selecione Configurações de Build de Arquivo>.
  • Selecione Windows Store na lista Plataforma e clique em Alternar Plataforma.
  • Defina o SDK como Universal 10 e o Tipo de Build comoD3D.
  • Verifique projetos C# do Unity.
  • Clique em Adicionar Cenas Abertas para adicionar a cena.
  • Clique em Configurações do Player....
  • No Painel do Inspetor, selecione o logotipo da Windows Store. Em seguida, selecione Configurações de Publicação.
  • Na seção Funcionalidades , selecione os recursos Microfone e SpatialPerception .
  • De volta à janela Configurações de Build, clique em Compilar.
  • Crie uma nova pasta chamada "App".
  • Clique apenas na Pasta do Aplicativo.
  • Pressione Selecionar Pasta.
  • Quando o Unity for concluído, uma janela Explorador de Arquivos será exibida.
  • Abra a pasta Aplicativo .
  • Abra a Solução Do Visual Studio do Origami.
  • Usando a barra de ferramentas superior no Visual Studio, altere o destino de Depuração para Lançamento e do ARM para X86.
    • Clique na seta ao lado do botão Dispositivo e selecione Emulador do HoloLens.
    • Clique em Depurar –> Iniciar sem depuração ou pressione Ctrl + F5.
    • Após algum tempo, o emulador começará com o projeto Origami. Ao iniciar o emulador pela primeira vez, pode levar até 15 minutos para que o emulador seja iniciado. Depois que ele for iniciado, não feche-o.

Capítulo 2 – Foco

Neste capítulo, apresentaremos a primeira de três maneiras de interagir com seus hologramas: olhar.

Objetivos

  • Visualize seu foco usando um cursor bloqueado pelo mundo.

Instruções

  • Voltar ao projeto do Unity e feche a janela Configurações de Build se ela ainda estiver aberta.
  • Selecione a pasta Hologramas no painel Projeto.
  • Arraste o objeto Cursor para o painel Hierarquia no nível raiz.
  • Clique duas vezes no objeto Cursor para dar uma olhada mais de perto.
  • Clique com o botão direito do mouse na pasta Scripts no painel Projeto.
  • Clique no submenu Criar .
  • Selecione Script C#.
  • Nomeie o script WorldCursor. Observação: o nome diferencia maiúsculas de minúsculas. Você não precisa adicionar a extensão .cs.
  • Selecione o objeto Cursor no painel Hierarquia.
  • Arraste e solte o script WorldCursor no painel Inspetor.
  • Clique duas vezes no script WorldCursor para abri-lo no Visual Studio.
  • Copie e cole esse código em WorldCursor.cs e Salve Tudo.
using UnityEngine;

public class WorldCursor : MonoBehaviour
{
    private MeshRenderer meshRenderer;

    // Use this for initialization
    void Start()
    {
        // Grab the mesh renderer that's on the same object as this script.
        meshRenderer = this.gameObject.GetComponentInChildren<MeshRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        // Do a raycast into the world based on the user's
        // head position and orientation.
        var headPosition = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;

        RaycastHit hitInfo;

        if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
        {
            // If the raycast hit a hologram...
            // Display the cursor mesh.
            meshRenderer.enabled = true;

            // Move thecursor to the point where the raycast hit.
            this.transform.position = hitInfo.point;

            // Rotate the cursor to hug the surface of the hologram.
            this.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
        }
        else
        {
            // If the raycast did not hit a hologram, hide the cursor mesh.
            meshRenderer.enabled = false;
        }
    }
}
  • Recompile o aplicativo a partir das Configurações de Build de Arquivo>.
  • Retorne à solução do Visual Studio usada anteriormente para implantar no emulador.
  • Selecione 'Recarregar Tudo' quando solicitado.
  • Clique em Depurar –> Iniciar Sem depuração ou pressione Ctrl + F5.
  • Use o controlador xbox para olhar ao redor da cena. Observe como o cursor interage com a forma de objetos.

Capítulo 3 – Gestos

Neste capítulo, adicionaremos suporte para gestos. Quando o usuário selecionar uma esfera de papel, faremos a esfera cair ativando a gravidade usando o mecanismo de física do Unity.

Objetivos

  • Controle os hologramas com o gesto Selecionar.

Instruções

Começaremos criando um script que pode detectar o gesto Selecionar.

  • Na pasta Scripts , crie um script chamado GazeGestureManager.
  • Arraste o script GazeGestureManager para o objeto OrigamiCollection na Hierarquia.
  • Abra o script GazeGestureManager no Visual Studio e adicione o seguinte código:
using UnityEngine;
using UnityEngine.XR.WSA.Input;

public class GazeGestureManager : MonoBehaviour
{
    public static GazeGestureManager Instance { get; private set; }

    // Represents the hologram that is currently being gazed at.
    public GameObject FocusedObject { get; private set; }

    GestureRecognizer recognizer;

    // Use this for initialization
    void Start()
    {
        Instance = this;

        // Set up a GestureRecognizer to detect Select gestures.
        recognizer = new GestureRecognizer();
        recognizer.Tapped += (args) =>
        {
            // Send an OnSelect message to the focused object and its ancestors.
            if (FocusedObject != null)
            {
                FocusedObject.SendMessageUpwards("OnSelect", SendMessageOptions.DontRequireReceiver);
            }
        };
        recognizer.StartCapturingGestures();
    }

    // Update is called once per frame
    void Update()
    {
        // Figure out which hologram is focused this frame.
        GameObject oldFocusObject = FocusedObject;

        // Do a raycast into the world based on the user's
        // head position and orientation.
        var headPosition = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;

        RaycastHit hitInfo;
        if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
        {
            // If the raycast hit a hologram, use that as the focused object.
            FocusedObject = hitInfo.collider.gameObject;
        }
        else
        {
            // If the raycast did not hit a hologram, clear the focused object.
            FocusedObject = null;
        }

        // If the focused object changed this frame,
        // start detecting fresh gestures again.
        if (FocusedObject != oldFocusObject)
        {
            recognizer.CancelGestures();
            recognizer.StartCapturingGestures();
        }
    }
}
  • Crie outro script na pasta Scripts, desta vez chamado SphereCommands.
  • Expanda o objeto OrigamiCollection na exibição Hierarquia.
  • Arraste o script SphereCommands para o objeto Sphere1 no painel Hierarquia.
  • Arraste o script SphereCommands para o objeto Sphere2 no painel Hierarquia.
  • Abra o script no Visual Studio para edição e substitua o código padrão por este:
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    // Called by GazeGestureManager when the user performs a Select gesture
    void OnSelect()
    {
        // If the sphere has no Rigidbody component, add one to enable physics.
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = this.gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }
}
  • Exporte, compile e implante o aplicativo no emulador do HoloLens.
  • Olhe ao redor da cena e centralize-se em uma das esferas.
  • Pressione o botão A no controlador do Xbox ou pressione a Barra de espaços para simular o gesto Selecionar.

Capítulo 4 – Voz

Neste capítulo, adicionaremos suporte para dois comandos de voz: "Redefinir mundo" para retornar as esferas descartadas para o local original e "Remover esfera" para fazer a esfera cair.

Objetivos

  • Adicione comandos de voz que sempre escutam em segundo plano.
  • Crie um holograma que reage a um comando de voz.

Instruções

  • Na pasta Scripts , crie um script chamado SpeechManager.
  • Arraste o script SpeechManager para o objeto OrigamiCollection na Hierarquia
  • Abra o script SpeechManager no Visual Studio.
  • Copie e cole esse código em SpeechManager.cs e Salve Tudo:
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.Speech;

public class SpeechManager : MonoBehaviour
{
    KeywordRecognizer keywordRecognizer = null;
    Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();

    // Use this for initialization
    void Start()
    {
        keywords.Add("Reset world", () =>
        {
            // Call the OnReset method on every descendant object.
            this.BroadcastMessage("OnReset");
        });

        keywords.Add("Drop Sphere", () =>
        {
            var focusObject = GazeGestureManager.Instance.FocusedObject;
            if (focusObject != null)
            {
                // Call the OnDrop method on just the focused object.
                focusObject.SendMessage("OnDrop", SendMessageOptions.DontRequireReceiver);
            }
        });

        // Tell the KeywordRecognizer about our keywords.
        keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());

        // Register a callback for the KeywordRecognizer and start recognizing!
        keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
        keywordRecognizer.Start();
    }

    private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
    {
        System.Action keywordAction;
        if (keywords.TryGetValue(args.text, out keywordAction))
        {
            keywordAction.Invoke();
        }
    }
}
  • Abra o script SphereCommands no Visual Studio.
  • Atualize o script para ler da seguinte maneira:
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    Vector3 originalPosition;

    // Use this for initialization
    void Start()
    {
        // Grab the original local position of the sphere when the app starts.
        originalPosition = this.transform.localPosition;
    }

    // Called by GazeGestureManager when the user performs a Select gesture
    void OnSelect()
    {
        // If the sphere has no Rigidbody component, add one to enable physics.
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = this.gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }

    // Called by SpeechManager when the user says the "Reset world" command
    void OnReset()
    {
        // If the sphere has a Rigidbody component, remove it to disable physics.
        var rigidbody = this.GetComponent<Rigidbody>();
        if (rigidbody != null)
        {
            rigidbody.isKinematic = true;
            Destroy(rigidbody);
        }

        // Put the sphere back into its original local position.
        this.transform.localPosition = originalPosition;
    }

    // Called by SpeechManager when the user says the "Drop sphere" command
    void OnDrop()
    {
        // Just do the same logic as a Select gesture.
        OnSelect();
    }
}
  • Exporte, compile e implante o aplicativo no emulador do HoloLens.
  • O emulador dará suporte ao microfone do computador e responderá à sua voz: ajuste o modo de exibição para que o cursor esteja em uma das esferas e diga "Drop Sphere".
  • Diga "Redefinir Mundo" para trazê-los de volta às suas posições iniciais.

Capítulo 5 – Som espacial

Neste capítulo, adicionaremos música ao aplicativo e dispararemos efeitos sonoros em determinadas ações. Usaremos o som espacial para fornecer aos sons um local específico no espaço 3D.

Objetivos

  • Ouça hologramas em seu mundo.

Instruções

  • No Unity, selecione no menu superior Editar > Áudio das Configurações > do Projeto
  • Localize a configuração Plug-in do Espacializador e selecione Espacializador MS HRTF.
  • Na pasta Hologramas , arraste o objeto Ambience para o objeto OrigamiCollection no Painel hierarquia.
  • Selecione OrigamiCollection e localize o componente Fonte de Áudio . Altere estas propriedades:
    • Verifique a propriedade Spatialize .
    • Verifique o Play On Awake.
    • Altere o Spatial Blend para 3D arrastando o controle deslizante até a direita.
    • Verifique a propriedade Loop .
    • Expanda Configurações de Som 3D e insira0,1 para Nível do Doppler.
    • Defina Rolloff de Volume como Rolloff Logarítmico.
    • Defina Distância Máxima como 20.
  • Na pasta Scripts , crie um script chamado SphereSounds.
  • Arraste SphereSounds para os objetos Sphere1 e Sphere2 na Hierarquia.
  • Abra SphereSounds no Visual Studio, atualize o código a seguir e Salve Tudo.
using UnityEngine;

public class SphereSounds : MonoBehaviour
{
    AudioSource impactAudioSource = null;
    AudioSource rollingAudioSource = null;

    bool rolling = false;

    void Start()
    {
        // Add an AudioSource component and set up some defaults
        impactAudioSource = gameObject.AddComponent<AudioSource>();
        impactAudioSource.playOnAwake = false;
        impactAudioSource.spatialize = true;
        impactAudioSource.spatialBlend = 1.0f;
        impactAudioSource.dopplerLevel = 0.0f;
        impactAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        impactAudioSource.maxDistance = 20f;

        rollingAudioSource = gameObject.AddComponent<AudioSource>();
        rollingAudioSource.playOnAwake = false;
        rollingAudioSource.spatialize = true;
        rollingAudioSource.spatialBlend = 1.0f;
        rollingAudioSource.dopplerLevel = 0.0f;
        rollingAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        rollingAudioSource.maxDistance = 20f;
        rollingAudioSource.loop = true;

        // Load the Sphere sounds from the Resources folder
        impactAudioSource.clip = Resources.Load<AudioClip>("Impact");
        rollingAudioSource.clip = Resources.Load<AudioClip>("Rolling");
    }

    // Occurs when this object starts colliding with another object
    void OnCollisionEnter(Collision collision)
    {
        // Play an impact sound if the sphere impacts strongly enough.
        if (collision.relativeVelocity.magnitude >= 0.1f)
        {
            impactAudioSource.Play();
        }
    }

    // Occurs each frame that this object continues to collide with another object
    void OnCollisionStay(Collision collision)
    {
        Rigidbody rigid = gameObject.GetComponent<Rigidbody>();

        // Play a rolling sound if the sphere is rolling fast enough.
        if (!rolling && rigid.velocity.magnitude >= 0.01f)
        {
            rolling = true;
            rollingAudioSource.Play();
        }
        // Stop the rolling sound if rolling slows down.
        else if (rolling && rigid.velocity.magnitude < 0.01f)
        {
            rolling = false;
            rollingAudioSource.Stop();
        }
    }

    // Occurs when this object stops colliding with another object
    void OnCollisionExit(Collision collision)
    {
        // Stop the rolling sound if the object falls off and stops colliding.
        if (rolling)
        {
            rolling = false;
            impactAudioSource.Stop();
            rollingAudioSource.Stop();
        }
    }
}
  • Salve o script e retorne ao Unity.
  • Exporte, compile e implante o aplicativo no emulador do HoloLens.
  • Use fones de ouvido para obter o efeito completo e se aproxime cada vez mais do Palco para ouvir os sons mudarem.

Capítulo 6 – Mapeamento espacial

Agora vamos usar o mapeamento espacial para colocar o tabuleiro do jogo em um objeto real no mundo real.

Objetivos

  • Traga seu mundo real para o mundo virtual.
  • Coloque seus hologramas onde eles são mais importantes para você.

Instruções

  • Clique na pasta Hologramas no painel Projeto.
  • Arraste o ativo mapeamento espacial para a raiz da Hierarquia.
  • Clique no objeto Mapeamento Espacial na Hierarquia.
  • No painel Inspetor, altere as seguintes propriedades:
    • Marque a caixa Desenhar Malhas Visuais .
    • Localize Desenhar Material e clique no círculo à direita. Digite "wireframe" no campo de pesquisa na parte superior. Clique no resultado e feche a janela.
  • Exporte, compile e implante o aplicativo no emulador do HoloLens.
  • Quando o aplicativo for executado, uma malha de uma sala de estar do mundo real verificada anteriormente será renderizada em wireframe.
  • Veja como uma esfera rolando cairá do palco e no chão!

Agora, mostraremos como mover o OrigamiCollection para um novo local:

  • Na pasta Scripts , crie um script chamado TapToPlaceParent.
  • Na Hierarquia, expanda o OrigamiCollection e selecione o objeto Stage .
  • Arraste o script TapToPlaceParent para o objeto Stage.
  • Abra o script TapToPlaceParent no Visual Studio e atualize-o para ser o seguinte:
using UnityEngine;

public class TapToPlaceParent : MonoBehaviour
{
    bool placing = false;

    // Called by GazeGestureManager when the user performs a Select gesture
    void OnSelect()
    {
        // On each Select gesture, toggle whether the user is in placing mode.
        placing = !placing;

        // If the user is in placing mode, display the spatial mapping mesh.
        if (placing)
        {
            SpatialMapping.Instance.DrawVisualMeshes = true;
        }
        // If the user is not in placing mode, hide the spatial mapping mesh.
        else
        {
            SpatialMapping.Instance.DrawVisualMeshes = false;
        }
    }

    // Update is called once per frame
    void Update()
    {
        // If the user is in placing mode,
        // update the placement to match the user's gaze.

        if (placing)
        {
            // Do a raycast into the world that will only hit the Spatial Mapping mesh.
            var headPosition = Camera.main.transform.position;
            var gazeDirection = Camera.main.transform.forward;

            RaycastHit hitInfo;
            if (Physics.Raycast(headPosition, gazeDirection, out hitInfo,
                30.0f, SpatialMapping.PhysicsRaycastMask))
            {
                // Move this object's parent object to
                // where the raycast hit the Spatial Mapping mesh.
                this.transform.parent.position = hitInfo.point;

                // Rotate this object's parent object to face the user.
                Quaternion toQuat = Camera.main.transform.localRotation;
                toQuat.x = 0;
                toQuat.z = 0;
                this.transform.parent.rotation = toQuat;
            }
        }
    }
}
  • Exportar, compilar e implantar o aplicativo.
  • Agora você deve ser capaz de colocar o jogo em um local específico olhando para ele, usando o gesto Selecionar (A ou Barra de Espaços) e, em seguida, movendo-se para um novo local e usando o gesto Selecionar novamente.

Fim

E esse é o fim deste tutorial!

Você aprendeu a:

  • Como criar um aplicativo holográfico no Unity.
  • Como fazer uso de foco, gesto, voz, sons e mapeamento espacial.
  • Como criar e implantar um aplicativo usando o Visual Studio.

Agora você está pronto para começar a criar seus próprios aplicativos holográficos!

Confira também