HoloLens (1-го поколения) Основные сведения 101: завершение проекта с помощью устройства


Важно!

Руководства по Смешанная реальность Academy были разработаны с помощью HoloLens (1-го поколения), Unity 2017 и Смешанная реальность иммерсивных гарнитур. Поэтому мы считаем, что важно оставить эти руководства для разработчиков, которые ищут рекомендации по разработке для этих устройств. Эти учебники не будут обновлены с учетом последних наборов инструментов или взаимодействий, используемых для HoloLens 2 и могут быть несовместимы с более новыми версиями Unity. Они будут сохранены для работы на поддерживаемых устройствах. Опубликован новый цикл руководств для HoloLens 2.


В этом руководстве описывается полный проект, встроенный в Unity, который демонстрирует основные функции Windows Mixed Reality holoLens, включая взгляд, жесты, голосовой ввод, пространственный звук и пространственное сопоставление.

Выполнение руководства займет около 1 часа.

Поддержка устройств

Курс HoloLens Иммерсивные гарнитуры
101. Основы смешанной реальности: полный проект с использованием устройства ✔️

Прежде чем начать

Предварительные условия

Файлы проекта

  • Скачайте файлы , необходимые для проекта. Требуется Unity 2017.2 или более поздней версии.
    • Если вам по-прежнему нужна поддержка Unity 5.6, используйте этот выпуск.
    • Если вам по-прежнему нужна поддержка Unity 5.5, используйте этот выпуск.
    • Если вам по-прежнему нужна поддержка Unity 5.4, используйте этот выпуск.
  • Отмените архивацию файлов на рабочем столе или в другом удобном расположении. Оставьте имя папки Origami.

Примечание

Если вы хотите просмотреть исходный код перед скачиванием, он доступен на сайте GitHub.

Глава 1. Мир "Holo"

В этой главе мы настроим наш первый проект Unity и пошагово выполните процесс сборки и развертывания.

Задачи

  • Настройка Unity для голографической разработки.
  • Создание голограммы.
  • Просмотрите голограмму, которую вы сделали.

Instructions

  • Запустите Unity.
  • Выберите Открыть.
  • Введите расположение в качестве папки Origami , которая была ранее не архивирована.
  • Выберите Origami и щелкните Выбрать папку.
  • Так как проект Origami не содержит сцены, сохраните пустую сцену по умолчанию в новый файл с помощью файла / Сохранить сцену как.
  • Присвойте новой сцене имя Origami и нажмите кнопку Сохранить .

Настройка виртуальной камеры main

  • На панели Иерархия выберите объект Main Camera.
  • В инспекторе задайте положение преобразования 0,0,0.
  • Найдите свойство Clear Flags и измените раскрывающийся список с Skybox на Сплошной цвет.
  • Щелкните поле Фон, чтобы открыть палитру.
  • Задайте для R, G, B, and A (Красный, зеленый, синий и альфа-компонент) значение 0.

Настройка сцены

  • На панели иерархии щелкните Создать и Создать пустое.
  • Щелкните правой кнопкой мыши новый GameObject и выберите Переименовать. Переименуйте GameObject в OrigamiCollection.
  • В папке Holograms на панели проекта (разверните узел Активы и выберите Голограммы или дважды щелкните папку Holograms на панели проекта):
    • Перетащите Stage в иерархию, чтобы стать дочерним элементом OrigamiCollection.
    • Перетащите Sphere1 в иерархию, чтобы стать дочерним элементом OrigamiCollection.
    • Перетащите Sphere2 в иерархию, чтобы стать дочерним элементом OrigamiCollection.
  • Щелкните правой кнопкой мыши объект Directional Light на панели иерархии и выберите Удалить.
  • Из папки Holograms перетащите Lights в корень панели иерархии.
  • В иерархии выберите OrigamiCollection.
  • В инспекторе задайте для преобразования положение 0, -0,5, 2,0.
  • Нажмите кнопку Воспроизвести в Unity, чтобы просмотреть голограммы.
  • Объекты Origami должны отображаться в окне предварительного просмотра.
  • Нажмите воспроизвести во второй раз, чтобы остановить режим предварительного просмотра.

Экспорт проекта из Unity в Visual Studio

  • В Unity выберите Параметры сборки файлов>.

  • Выберите универсальная платформа Windows в списке Платформа и щелкните Переключить платформу.

  • Установите для пакета SDKзначение Universal 10 , а для параметра Тип сборкизначение D3D.

  • Проверьте проекты Unity C#.

  • Щелкните Добавить открытые сцены , чтобы добавить сцену.

  • Щелкните Построить.

  • В появившемся окне проводника создайте новую папку с именем App.

  • Одним щелчком мыши щелкните папку приложения.

  • Нажмите кнопку Выбрать папку.

  • После завершения работы Unity появится окно проводник.

  • Откройте папку Приложение .

  • Откройте (дважды щелкните) Origami.sln.

  • С помощью верхней панели инструментов Visual Studio измените целевой объект с Отладка на Выпуск и с ARM на X86.

  • Щелкните стрелку рядом с кнопкой Устройство и выберите Удаленный компьютер для развертывания через Wi-Fi.

    • Задайте в поле Адрес имя или IP-адрес HoloLens. Если вы не знаете IP-адрес устройства, найдите в разделе Параметры > Сетевые & Дополнительные параметры Браузера > или спросите Кортану "Привет, Кортана, что мой IP-адрес?"
    • Если HoloLens подключен через USB, вместо этого можно выбрать Устройство для развертывания через USB.
    • Оставьте для параметра Режим проверки подлинности значение Универсальный.
    • Нажмите кнопку Выбрать.
  • Щелкните Отладка > Начать без отладки или нажмите клавиши CTRL+F5. Если развертывание на устройстве выполняется впервые, необходимо связать его с Visual Studio.

  • Теперь проект Origami будет выполнять сборку, развертывание в HoloLens, а затем запуск.

  • Наденьте HoloLens и посмотрите вокруг, чтобы увидеть новые голограммы.

Глава 2. Взгляд

В этой главе мы представим первый из трех способов взаимодействия с голограммами — взгляд.

Задачи

  • Визуализируйте взгляд с помощью курсора, заблокированного во всем мире.

Instructions

  • Назад в проект Unity и закройте окно Параметры сборки, если оно все еще открыто.
  • Выберите папку Голограммы на панели Проект.
  • Перетащите объект Cursor на панель Иерархия на корневом уровне.
  • Дважды щелкните объект Cursor , чтобы рассмотреть его внимательнее.
  • Щелкните правой кнопкой мыши папку Скрипты на панели Проект.
  • Щелкните подменю Создать .
  • Выберите Скрипт C#.
  • Назовите скрипт WorldCursor. Примечание. Имя учитывает регистр. Вам не нужно добавлять расширение .cs.
  • Выберите объект Cursor на панели Иерархия.
  • Перетащите скрипт WorldCursor на панель Инспектор.
  • Дважды щелкните скрипт WorldCursor, чтобы открыть его в Visual Studio.
  • Скопируйте и вставьте этот код в Файл WorldCursor.cs и Сохранить все.
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 the cursor 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;
        }
    }
}
  • Перестройте приложение из параметров сборки файлов>.
  • Вернитесь к решению Visual Studio, которое ранее использовалось для развертывания в HoloLens.
  • При появлении запроса выберите "Перезагрузить все".
  • Щелкните Отладка —> запуск без отладки или нажмите клавиши CTRL+F5.
  • Теперь посмотрите вокруг сцены и обратите внимание, как курсор взаимодействует с формой объектов.

Глава 3. Жесты

В этой главе мы добавим поддержку жестов. Когда пользователь выбирает бумажную сферу, мы упадем сферу, включив гравитацию с помощью физического механизма Unity.

Задачи

  • Управляйте голограммами с помощью жеста Выбрать.

Instructions

Начнем с создания скрипта, а затем сможем обнаружить жест Выбрать.

  • В папке Scripts создайте скрипт с именем GazeGestureManager.
  • Перетащите скрипт GazeGestureManager в объект OrigamiCollection в иерархии.
  • Откройте скрипт GazeGestureManager в Visual Studio и добавьте следующий код:
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 Awake()
    {
        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();
        }
    }
}
  • Создайте в папке Scripts еще один скрипт с именем SphereCommands.
  • Разверните объект OrigamiCollection в представлении Иерархия.
  • Перетащите скрипт SphereCommands в объект Sphere1 на панели Иерархия.
  • Перетащите скрипт SphereCommands в объект Sphere2 на панели Иерархия.
  • Откройте скрипт в Visual Studio для редактирования и замените код по умолчанию следующим:
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;
        }
    }
}
  • Экспортируйте, создайте и разверните приложение в HoloLens.
  • Посмотрите на одну из сфер.
  • Выполните жест выбора и watch падения сферы на поверхность ниже.

Глава 4. Голос

В этой главе мы добавим поддержку двух голосовых команд: "Сброс мира", чтобы вернуть удаленные сферы в исходное расположение, и "Drop sphere", чтобы сделать сферу падает.

Задачи

  • Добавьте голосовые команды, которые всегда прослушивают в фоновом режиме.
  • Создайте голограмму, которая реагирует на голосовую команду.

Instructions

  • В папке Scripts создайте скрипт с именем SpeechManager.
  • Перетащите скрипт SpeechManager в объект OrigamiCollection в иерархии.
  • Откройте скрипт SpeechManager в Visual Studio.
  • Скопируйте и вставьте этот код в SpeechManager.cs и сохранить все:
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();
        }
    }
}
  • Откройте скрипт SphereCommands в Visual Studio.
  • Обновите скрипт следующим образом:
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();
    }
}
  • Экспортируйте, создайте и разверните приложение в HoloLens.
  • Посмотрите на одну из сфер и произнесите "Drop Sphere".
  • Скажите "Reset World", чтобы вернуть их в исходное положение.

Глава 5. Пространственный звук

В этой главе мы добавим музыку в приложение, а затем активируем звуковые эффекты для определенных действий. Мы будем использовать пространственный звук , чтобы дать звуку определенное расположение в трехмерном пространстве.

Задачи

  • Слушайте голограммы в вашем мире.

Instructions

  • В Unity выберите в верхнем меню Изменить > параметры проекта Аудио >
  • На панели инспектора справа найдите параметр Подключаемый модуль Spatializer и выберите MS HRTF Spatializer.
  • Из папки Holograms на панели Проект перетащите объект Ambience в объект OrigamiCollection на панели иерархии.
  • Выберите OrigamiCollection и найдите компонент Источник звука на панели Инспектор. Измените следующие свойства:
    • Проверьте свойство Spatialize .
    • Проверьте воспроизведение при пробуждении.
    • Измените значение Spatial Blend на трехмерный, перетащив ползунок вправо. При перемещении ползунка значение должно измениться с 0 на 1.
    • Проверьте свойство Loop .
    • Разверните узел Параметры трехмерного звука и введите 0.1 в поле Уровень доплеров.
    • Присвойте параметру Volume Rolloff значение Logarithmic Rolloff.
    • Задайте для параметра Максимальное расстояниезначение 20.
  • В папке Scripts создайте скрипт с именем SphereSounds.
  • Перетащите SphereSounds в объекты Sphere1 и Sphere2 в иерархии.
  • Откройте SphereSounds в Visual Studio, обновите следующий код и сохраните все.
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();
        }
    }
}
  • Сохраните скрипт и вернитесь в Unity.
  • Экспортируйте, создайте и разверните приложение в HoloLens.
  • Перемещайтесь все ближе и дальше от сцены и поворачивайтесь из стороны в сторону, чтобы услышать изменение звуков.

Глава 6. Пространственное сопоставление

Теперь мы будем использовать пространственное сопоставление для размещения игровой доски на реальном объекте в реальном мире.

Задачи

  • Принесите свой реальный мир в виртуальный мир.
  • Размещайте голограммы там, где они наиболее важны для вас.

Instructions

  • В Unity щелкните папку Голограммы на панели Проект.
  • Перетащите ресурс Пространственное сопоставление в корень иерархии.
  • Щелкните объект Пространственное сопоставление в иерархии.
  • На панели Инспектор измените следующие свойства:
    • Установите флажок Рисование визуальных сеток .
    • Найдите элемент Рисование материала и щелкните круг справа. Введите "wireframe" в поле поиска вверху. Щелкните результат и закройте окно. При этом для параметра Draw Material должно быть задано значение Wireframe.
  • Экспортируйте, создайте и разверните приложение в HoloLens.
  • При запуске приложения сетка каркаса накроет ваш реальный мир.
  • Посмотрите, как скользящий шар упадет со сцены, и на пол!

Теперь мы покажем, как переместить коллекцию OrigamiCollection в новое расположение:

  • В папке Scripts создайте скрипт с именем TapToPlaceParent.
  • В иерархии разверните OrigamiCollection и выберите объект Stage .
  • Перетащите скрипт TapToPlaceParent в объект Stage.
  • Откройте скрипт TapToPlaceParent в Visual Studio и обновите его следующим образом:
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;
            }
        }
    }
}
  • Экспорт, сборка и развертывание приложения.
  • Теперь вы сможете разместить игру в определенном месте, взглянув на нее, используя жест Выбрать, а затем переместив в новое место, а затем снова используя жест Выбрать.

Глава 7. Голографическое веселье

Задачи

  • Раскрой вход в голографический подземный мир.

Instructions

Теперь мы покажем, как раскрыть голографический подземный мир:

  • В папке Holograms на панели проектов :
    • Перетащите Underworld в иерархию, чтобы стать дочерним элементом OrigamiCollection.
  • В папке Scripts создайте скрипт с именем HitTarget.
  • В иерархии разверните коллекцию OrigamiCollection.
  • Разверните объект Stage и выберите целевой объект (синий вентилятор).
  • Перетащите скрипт HitTarget в объект Target .
  • Откройте скрипт HitTarget в Visual Studio и обновите его следующим образом:
using UnityEngine;

public class HitTarget : MonoBehaviour
{
    // These public fields become settable properties in the Unity editor.
    public GameObject underworld;
    public GameObject objectToHide;

    // Occurs when this object starts colliding with another object
    void OnCollisionEnter(Collision collision)
    {
        // Hide the stage and show the underworld.
        objectToHide.SetActive(false);
        underworld.SetActive(true);

        // Disable Spatial Mapping to let the spheres enter the underworld.
        SpatialMapping.Instance.MappingEnabled = false;
    }
}
  • В Unity выберите целевой объект.
  • Два открытых свойства теперь отображаются в компоненте Hit Target и должны ссылаться на объекты в нашей сцене:
    • Перетащите Underworld с панели Иерархия в свойство Underworld компонента Hit Target (Целевой объект попадания ).
    • Перетащите элемент Stage с панели Иерархия в свойство Object to Hide (Объект для скрытия) компонента Hit Target (Целевой объект попадания).
  • Экспорт, сборка и развертывание приложения.
  • Поместите коллекцию Origami на пол, а затем с помощью жеста Выбрать упадите сферу.
  • Когда сфера попадает в цель (синий вентилятор), происходит взрыв. Коллекция будет скрыта и появится отверстие в преисподней.

Конец

И это конец этого учебника!

Вы узнали:

  • Создание голографического приложения в Unity.
  • Использование взгляда, жеста, голоса, звука и пространственного сопоставления.
  • Создание и развертывание приложения с помощью Visual Studio.

Теперь вы готовы приступить к созданию собственного голографического интерфейса!

См. также раздел