Partilhar via


HoloLens (1.ª geração) Basics 101E: Concluir o projeto com o emulador

Importante

Os tutoriais Mixed Reality Academy foram concebidos com HoloLens (1.ª geração), Unity 2017 e Mixed Reality Headsets Envolventes em mente. Como tal, consideramos importante deixar estes tutoriais em vigor para os programadores que ainda estão à procura de orientação no desenvolvimento desses dispositivos. Estes tutoriais não serão atualizados com os conjuntos de ferramentas ou interações mais recentes utilizados para HoloLens 2 e poderão não ser compatíveis com versões mais recentes do Unity. Serão mantidas para continuarem a trabalhar nos dispositivos suportados. Foi publicada uma nova série de tutoriais para HoloLens 2.


Este tutorial irá guiá-lo através de um projeto completo, incorporado no Unity, que demonstra as principais funcionalidades Windows Mixed Reality no HoloLens, incluindo olhar,gestos, entrada de voz, som espacial e mapeamento espacial. O tutorial demorará aproximadamente 1 hora a ser concluído.

Suporte de dispositivos

Curso HoloLens Headsets envolventes
MR Basics 101E: Concluir o projeto com o emulador ✔️

Antes de começar

Pré-requisitos

Ficheiros de projeto

  • Transfira os ficheiros necessários para o projeto. Requer o Unity 2017.2 ou posterior.
    • Se ainda precisar de suporte para o Unity 5.6, utilize esta versão.
    • Se ainda precisar de suporte para o Unity 5.5, utilize esta versão.
    • Se ainda precisar de suporte para o Unity 5.4, utilize esta versão.
  • Remova o arquivo dos ficheiros para o seu ambiente de trabalho ou outra localização fácil de aceder. Mantenha o nome da pasta como Origami.

Nota

Se quiser ver o código fonte antes de transferir, este estará disponível no GitHub.

Capítulo 1 - Mundo "Holo"

Neste capítulo, vamos configurar o nosso primeiro projeto do Unity e percorrer o processo de compilação e implementação.

Objetivos

  • Configurar o Unity para desenvolvimento holográfico.
  • Criar um holograma.
  • Veja um holograma que criou.

Instruções

  • Inicie o Unity.
  • Selecione Abrir.
  • Introduza a localização como a pasta Origami que desvendou anteriormente.
  • Selecione Origami e clique em Selecionar Pasta.
  • Guarde a nova cena:Cenário guardarficheiro / como.
  • Dê um nome à cena Origami e prima o botão Guardar .

Configurar a câmara principal

  • No Painel hierarquia, selecione Câmara Principal.
  • No Inspetor , defina a sua posição de transformação para 0,0,0.
  • Localize a propriedade Limpar Sinalizadores e altere o menu pendente de Skybox para Cor sólida.
  • Clique no campo Fundo para abrir um seletor de cores.
  • Defina R, G, B e A como 0.

Configurar o cenário

  • No Painel hierarquia, clique em Criar e Criar Vazio.
  • Clique com o botão direito do rato no novo GameObject e selecione Mudar o Nome. Mude o nome do GameObject para OrigamiCollection.
  • A partir da pasta Hologramas no Painel de Projeto:
    • Arraste Fase para a Hierarquia para ser um subordinado de OrigamiCollection.
    • Arraste Sphere1 para a Hierarquia para ser subordinado de OrigamiCollection.
    • Arraste Sphere2 para a Hierarquia para ser subordinado de OrigamiCollection.
  • Clique com o botão direito do rato no objeto Luz Direcional no Painel de Hierarquia e selecione Eliminar.
  • Na pasta Hologramas , arraste Luzes 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.
  • Prima o botão Reproduzir no Unity para pré-visualizar os hologramas.
  • Deverá ver os objetos Origami na janela de pré-visualização.
  • Prima Reproduzir uma segunda vez para parar o modo de pré-visualização.

Exportar o projeto do Unity para o Visual Studio

  • No Unity, selecione Definições de Compilação de Ficheiros>.
  • Selecione Loja Windows na lista Plataforma e clique em Mudar de Plataforma.
  • Defina o SDK como Universal 10 e o Tipo de Compilação como D3D.
  • Verifique Projetos C# do Unity.
  • Clique em Adicionar Cenas Abertas para adicionar a cena.
  • Clique em Definições do Leitor....
  • No Painel de Inspetor, selecione o logótipo da Loja Windows. Em seguida, selecione Definições de Publicação.
  • Na secção Capacidades , selecione as capacidades Microfone e SpatialPerception .
  • Novamente na janela Definições de Compilação, clique em Compilar.
  • Crie uma Nova Pasta com o nome "Aplicação".
  • Clique único na Pasta da Aplicação.
  • Prima Selecionar Pasta.
  • Quando o Unity estiver concluído, será apresentada uma janela de Explorador de Ficheiros.
  • Abra a pasta Aplicação .
  • Abra a Origami Visual Studio Solution.
  • Com a barra de ferramentas superior no Visual Studio, altere o destino de Depuração para Versão e de ARM para X86.
    • Clique na seta junto ao botão Dispositivo e selecione HoloLens Emulator.
    • Clique em Depurar -> Iniciar Sem depuração ou prima Ctrl + F5.
    • Após algum tempo, o emulador começará com o projeto Origami. Ao iniciar o emulador pela primeira vez, pode demorar até 15 minutos para o emulador iniciar. Assim que começar, não o feche.

Capítulo 2 - Olhar

Neste capítulo, vamos introduzir a primeira de três formas de interagir com os seus hologramas.

Objetivos

  • Visualize o olhar através de um cursor bloqueado pelo mundo.

Instruções

  • Voltar ao projeto do Unity e feche a janela Definições de Compilação se ainda estiver aberta.
  • Selecione a pasta Hologramas no painel Projeto.
  • Arraste o objeto Cursor para o painel Hierarquia ao nível da raiz.
  • Faça duplo clique no objeto Cursor para dar uma vista de olhos.
  • Clique com o botão direito do rato na pasta Scripts no painel Projeto.
  • Clique no submenu Criar .
  • Selecione Script C#.
  • Atribua o nome WorldCursor ao script. Nota: o nome é sensível às maiúsculas e minúsculas. Não precisa de adicionar a extensão .cs.
  • Selecione o objeto Cursor no painel Hierarquia.
  • Arraste e largue o script WorldCursor no painel Inspetor.
  • Faça duplo clique no script WorldCursor para o abrir no Visual Studio.
  • Copie e cole este código em WorldCursor.cs e Guarde 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;
        }
    }
}
  • Reconstrua a aplicação a partir das Definições de Compilação de Ficheiros>.
  • Regresse à solução do Visual Studio anteriormente utilizada para implementar no emulador.
  • Selecione "Recarregar Tudo" quando lhe for pedido.
  • Clique em Depurar –> Iniciar Sem depuração ou prima Ctrl + F5.
  • Utilize o comando Xbox para dar uma vista de olhos à cena. Repare como o cursor interage com a forma dos objetos.

Capítulo 3 - Gestos

Neste capítulo, vamos adicionar suporte para gestos. Quando o utilizador selecionar uma esfera de papel, faremos com que a esfera caia ao ativar a gravidade com o motor físico do Unity.

Objetivos

  • Controle os hologramas com o gesto Selecionar.

Instruções

Vamos começar por criar um script do que pode detetar o gesto Selecionar.

  • Na pasta Scripts , crie um script com o nome 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 denominado SphereCommands.
  • Expanda o objeto OrigamiCollection na vista 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 predefinido pelo seguinte:
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, crie e implemente a aplicação no emulador holoLens.
  • Olhe à volta da cena e concentre-se numa das esferas.
  • Prima o botão A no comando Xbox ou prima a Barra de Espaço para simular o gesto Selecionar.

Capítulo 4 - Voz

Neste capítulo, vamos adicionar suporte para dois comandos de voz: "Repor mundo" para devolver as esferas removidas à sua localização original e "Largar esfera" para que a esfera caia.

Objetivos

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

Instruções

  • Na pasta Scripts , crie um script com o nome SpeechManager.
  • Arraste o script SpeechManager para o objeto OrigamiCollection na Hierarquia
  • Abra o script SpeechManager no Visual Studio.
  • Copie e cole este código em SpeechManager.cs e Guarde 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 forma:
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, crie e implemente a aplicação no emulador holoLens.
  • O emulador irá suportar o microfone do PC e responder à sua voz: ajuste a vista para que o cursor esteja numa das esferas e diga "Largar Esfera".
  • Diga "Repor Mundo" para os trazer de volta às suas posições iniciais.

Capítulo 5 - Som espacial

Neste capítulo, vamos adicionar música à aplicação e, em seguida, acionar efeitos sonoros em determinadas ações. Vamos utilizar som espacial para dar aos sons uma localização específica no espaço 3D.

Objetivos

  • Ouvir hologramas no seu mundo.

Instruções

  • No Unity, selecione no menu superior Editar > Definições > do Projeto Áudio
  • Localize a definição Plug-in spatializer e selecione Ms HRTF Spatializer.
  • Na pasta Hologramas , arraste o objeto Ambiente para o objeto OrigamiCollection no Painel de Hierarquia.
  • Selecione OrigamiCollection e localize o componente Origem de Áudio . Alterar estas propriedades:
    • Verifique a propriedade Spatialize .
    • Verifique a funcionalidade Reproduzir Em Acordado.
    • Altere o Spatial Blend para 3D ao arrastar o controlo de deslize até à direita.
    • Verifique a propriedade Loop .
    • Expanda Definições de Som 3D e introduza 0.1 para o Nível do Doppler.
    • Defina Rolloff de Volume como Rolloff Logarítmico.
    • Defina a Distância Máxima como 20.
  • Na pasta Scripts , crie um script com o nome SphereSounds.
  • Arraste SphereSounds para os objetosSphere1 e Sphere2 na Hierarquia.
  • Abra o SphereSounds no Visual Studio, atualize o seguinte código e Guarde 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();
        }
    }
}
  • Guarde o script e regresse ao Unity.
  • Exporte, crie e implemente a aplicação no emulador holoLens.
  • Utilize auscultadores para obter o efeito completo e aproxime-se cada vez mais da Fase para ouvir os sons mudarem.

Capítulo 6 - Mapeamento espacial

Agora vamos usar o mapeamento espacial para colocar o tabuleiro de jogo num objeto real no mundo real.

Objetivos

  • Traga o seu mundo real para o mundo virtual.
  • Coloque os hologramas onde são mais importantes para si.

Instruções

  • Clique na pasta Hologramas no painel Projeto.
  • Arraste o recurso Mapeamento Espacial para a raiz da Hierarquia.
  • Clique no objeto Mapeamento Espacial na Hierarquia.
  • No painel Inspetor, altere as seguintes propriedades:
    • Selecione a caixa Desenhar Malhas Visuais .
    • Localize Desenhar Material e clique no círculo à direita. Escreva "wireframe" no campo de pesquisa na parte superior. Clique no resultado e, em seguida, feche a janela.
  • Exporte, crie e implemente a aplicação no emulador holoLens.
  • Quando a aplicação é executada, uma malha de uma sala de estar do mundo real previamente digitalizada será composta em wireframe.
  • Veja como uma esfera ondulante cairá do palco e no chão!

Agora, vamos mostrar-lhe como mover o OrigamiCollection para uma nova localização:

  • Na pasta Scripts , crie um script com o nome TapToPlaceParent.
  • Na Hierarquia, expanda OrigamiCollection e selecione o objeto Fase .
  • Arraste o script TapToPlaceParent para o objeto Fase.
  • 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, criar e implementar a aplicação.
  • Agora, deverá conseguir colocar o jogo numa localização específica ao olhar para o mesmo, utilizando o gesto Selecionar (A ou Barra de Espaço) e, em seguida, mudar para uma nova localização e utilizar novamente o gesto Selecionar.

O fim

E este é o fim deste tutorial!

Aprendeu:

  • Como criar uma aplicação holográfica no Unity.
  • Como utilizar o olhar, o gesto, a voz, os sons e o mapeamento espacial.
  • Como criar e implementar uma aplicação com o Visual Studio.

Está pronto para começar a criar as suas próprias aplicações holográficas!

Ver também