Блокировка мира и пространственные привязки в Unity
Статья
Обеспечение того, чтобы голограммы оставались на месте, перемещались вместе с вами или в некоторых случаях располагались относительно других голограмм, является важной частью создания Смешанная реальность приложений. В этой статье мы рассмотрим рекомендуемое решение с помощью World Locking Tools, но мы также рассмотрим настройку пространственных привязок вручную в проектах Unity. Прежде чем перейти к любому коду, важно понять, как Unity обрабатывает пространство координат и привязки в своем собственном механизме.
Системы координат мирового масштаба
Сегодня при написании игр, приложений для визуализации данных или приложений виртуальной реальности типичным подходом является создание одной абсолютной мировой системы координат , с которыми можно надежно сопоставить все остальные координаты. В этой среде всегда можно найти стабильное преобразование, определяющее связь между любыми двумя объектами в этом мире. Если вы не переместите эти объекты, их относительные преобразования всегда будут оставаться неизменными. Такого рода глобальную систему координат легко получить правильно при отрисовке чисто виртуального мира, где вы знаете всю геометрию заранее. Приложения виртуальной реальности в масштабе помещений сегодня, как правило, устанавливают такой вид абсолютной системы координат масштаба комнаты с ее происхождением на полу.
В отличие от этого, устройство смешанной реальности, такое как HoloLens, имеет динамическое понимание мира на основе датчика, постоянно корректируя свои знания с течением времени об окружающей среде пользователя, когда они ходят много метров по всему полу здания. В мировом масштабе, если поместить все голограммы в наивную жесткую систему координат, эти голограммы со временем будут дрейфовать на основе мира или относительно друг друга.
Например, гарнитура в настоящее время может считать, что два расположения в мире находятся на 4 метра друг от друга, а затем уточнить это понимание, узнав, что расположения на самом деле находятся на 3,9 метра друг от друга. Если бы эти голограммы изначально располагались на 4 метра друг от друга в одной жесткой системе координат, одна из них всегда появлялась бы на 0,1 метра от реального мира.
Вы можете вручную разместить пространственные привязки в Unity, чтобы сохранить положение голограммы в физическом мире, когда пользователь является мобильным. Однако это приносит в жертву самосогласованность в виртуальном мире. Различные привязки постоянно перемещаются по отношению друг к другу, а также перемещаются через глобальное пространство координат. В этом сценарии простые задачи, такие как макет, становятся сложными. Моделирование физики также может быть проблематичным.
World Locking Tools (WLT) предоставляет вам лучшее из обоих миров, стабилизируя единую жесткую систему координат с помощью внутренней поставки пространственных привязок, распределенных по всей виртуальной сцене по мере перемещения пользователя. WLT анализирует координаты камеры и эти пространственные привязки для каждого кадра. Вместо того, чтобы изменять координаты всего в мире, чтобы компенсировать исправления в координатах головы пользователя, WLT просто фиксирует координаты головы.
Выбор подхода к блокировке мира
Если это возможно, используйте World Locking Tools для размещения голограмм.
World Locking Tools предоставляет стабильную систему координат, которая сводит к минимуму видимые несоответствия между виртуальными и реальными маркерами. World Locking Tools блокирует всю сцену с помощью общего пула привязок, а не блокирует каждую группу объектов с помощью собственной отдельной привязки группы.
World Locking Tools автоматически обрабатывает внутреннее создание пространственных привязок и управление ими. Вам не нужно взаимодействовать с ARAnchorManager или WorldAnchor, чтобы ваши голограммы были заблокированы.
Для Unity 2019/2020 с использованием OpenXR или подключаемого модуля Windows XR используйте ARAnchorManager.
Для более старых версий Unity или проектов WSA используйте WorldAnchor.
Чтобы приступить к работе с World Locking Tools, скачайте средство Смешанная реальность Feature Tool. Дополнительные сведения об основах см. на странице документации по main World Locking Tools со ссылками на обзор, краткое руководство и другие полезные разделы.
Когда проект будет готов к работе, запустите служебную программу настройки сцены из Смешанная реальность > World Locking Tools:
Важно!
Программу Configure scene можно повторно запустить в любое время. Например, ее следует запустить повторно, если целевой объект AR был изменен с Legacy на XR SDK. Если сцена уже настроена правильно, запуск программы ничего не изменит.
Визуализаторы
Во время ранней разработки может быть полезно добавить визуализаторы, чтобы убедиться, что WLT настроен и работает правильно. Их можно удалить с помощью программы Remove visualizers для повышения производительности или если они больше не нужны. Дополнительные сведения о визуализаторах можно найти в документации по средствам.
Подключаемый модуль OpenXR Смешанная реальность предоставляет основные функции привязки через реализацию ARFoundation ARAnchorManager в Unity. Чтобы изучить основы ARAnchors в ARFoundation, ознакомьтесь с руководством по ARFoundation для диспетчера привязок AR.
Пространство имен:UnityEngine.XR.WSA Тип:WorldAnchor
Этот игровой объект теперь привязан к его текущему расположению в физическом мире. Вы можете увидеть, как его мировые координаты Unity немного изменяются с течением времени, чтобы обеспечить физическое выравнивание. Чтобы снова найти это привязанное расположение в следующем сеансе приложения, см. раздел Загрузка мировой привязки .
Удаление всемирной привязки
Если вы больше не хотите GameObject , чтобы объект был заблокирован в физическом мире и не планируете перемещать его этот кадр, вызовите Destroy компонент World Anchor.
Destroy(gameObject.GetComponent<WorldAnchor>());
Если вы хотите переместить GameObject этот кадр, вызовите DestroyImmediate вместо него .
Мировой якорь может быть недоступен в физическом мире в определенный момент времени. После этого Unity не будет обновлять преобразование привязанного объекта. Такая ситуация также может произойти во время работы приложения. Неспособность обработать изменение locatability приводит к тому, что объект не отображается в правильном физическом расположении в мире.
Чтобы получать уведомления об изменениях locatability, выполните приведенные далее действия.
Подпишитесь на OnTrackingChanged событие. Событие OnTrackingChanged вызывается всякий раз, когда базовая пространственная привязка изменяется между состоянием locatable или not locatable.
private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
// This simply activates/deactivates this object and all children when tracking changes
self.gameObject.SetActiveRecursively(located);
}
Если привязки находятся немедленно, при возврате isLocated свойству привязки присваивается значение trueAddComponent<WorldAnchor>() . OnTrackingChanged Поэтому событие не активируется. Более понятным шаблоном является вызов обработчика OnTrackingChanged с начальным IsLocated состоянием после присоединения привязки.
Пространственные привязки сохраняют голограммы в реальном пространстве между сеансами приложения. После сохранения в хранилище привязок HoloLens пространственные привязки можно найти и загрузить в разных сеансах и являются идеальным резервным вариантом при отсутствии подключения к Интернету.
Важно!
Локальные привязки хранятся на устройстве, а пространственные привязки Azure сохраняются в облаке. Вы можете использовать локальные привязки и привязки Azure в одном проекте без конфликтов. Дополнительные сведения об интеграции облачных служб Azure для хранения привязок см. в статье Пространственные привязки Azure.
По умолчанию World Locking Tools восстанавливает систему координат Unity относительно физического мира между сеансами на устройствах, поддерживающих сохранение локальных пространственных привязок. Чтобы голограмма отображалась в том же месте в физическом мире после выхода из приложения и повторного запуска приложения, приложению достаточно восстановить ту же позу голограммы.
Если приложению требуется более точное управление, вы можете отключить автосохранение и автозагрузку в инспекторе и управлять сохраняемостью из скрипта. Дополнительные сведения см. в разделе Сохранение систем пространственных координат.
World Locking Tools поддерживает сохранение локальных привязок только на устройствах HoloLens. Для устройств Android, iOS и HoloLens интегрируйте с Пространственными привязками Azure, чтобы поддерживать сохраняемость и совместное использование координатных пространств между сеансами и устройствами. Дополнительные сведения и примеры использования World Locking Tools с пространственными привязками Azure см. в статье World Locking Tools (WLT) в сочетании с пространственными привязками Azure (ASA).
API с именем XRAnchorStore позволяет сохранять привязки между сеансами. — XRAnchorStore это представление сохраненных привязок на устройстве. Вы можете сохранять привязки из ARAnchors в сцене Unity, загружать привязки из хранилища в новое ARAnchorsили удалять привязки из хранилища.
Примечание
Вы сохраняете и загружаете эти привязки на одном устройстве. Привязки между устройствами поддерживаются с помощью пространственных привязок Azure.
Пространства имен
Для Unity 2020 и OpenXR:
using Microsoft.MixedReality.ARSubsystems.XRAnchorStore
или Unity 2019/2020 + Подключаемый модуль Windows XR:
using UnityEngine.XR.WindowsMR.XRAnchorStore
Открытые методы
{
// A list of all persisted anchors, which can be loaded.
public IReadOnlyList<string> PersistedAnchorNames { get; }
// Clear all persisted anchors
public void Clear();
// Load a single persisted anchor by name. The ARAnchorManager will create this new anchor and report it in
// the ARAnchorManager.anchorsChanged event. The TrackableId returned here is the same TrackableId the
// ARAnchor will have when it is instantiated.
public TrackableId LoadAnchor(string name);
// Attempts to persist an existing ARAnchor with the given TrackableId to the local store. Returns true if
// the storage is successful, false otherwise.
public bool TryPersistAnchor(TrackableId id, string name);
// Removes a single persisted anchor from the anchor store. This will not affect any ARAnchors in the Unity
// scene, only the anchors in storage.
public void UnpersistAnchor(string name);
}
Получение ссылки на хранилище привязок
Чтобы загрузить XRAnchorStore с Unity 2020 и OpenXR, используйте метод расширения в XRAnchorSubsystem, подсистеме ARAnchorManager:
public static Task<XRAnchorStore> LoadAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem)
Чтобы загрузить XRAnchorStore с Unity 2019/2020 и подключаемым модулем Windows XR, используйте метод расширения в XRReferencePointSubsystem (Unity 2019) или XRAnchorSubsystem (Unity 2020), подсистеме ARReferencePointManager/ARAnchorManager:
// Unity 2019 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRReferencePointSubsystem anchorSubsystem);
// Unity 2020 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem);
Загрузка хранилища привязок
Чтобы загрузить хранилище привязок в Unity 2020 и OpenXR, получите к нему доступ из подсистемы ARAnchorManager следующим образом:
Чтобы просмотреть полный пример сохранения или отмены привязки, проверка скрипты Anchors — Anchors Sample> GameObject и AnchorsSample.cs в [Смешанная реальность Пример сцены подключаемого модуля OpenXR]((https://github.com/microsoft/OpenXR-Unity-MixedReality-Samples):
Для сохранения голограмм в более ранних версиях Unity или проектах WSA используйте WorldAnchor.
Пространство имен:UnityEngine.XR.WSA.Persistence Класс:WorldAnchorStore
WorldAnchorStore создает голографические интерфейсы, в которых голограммы остаются в определенных реальных положениях между экземплярами приложения. Пользователи могут закреплять отдельные голограммы в любом месте и находить их позже в том же месте во время сеансов приложения.
позволяет WorldAnchorStore сохранять расположение мировых привязок между сеансами. Чтобы сохранять голограммы в разных сеансах, отдельно отслеживайте GameObjects , которые используют определенную мировую привязку. Вы можете создать GameObject корень с мировой привязкой и привязать к нему дочерние голограммы с локальным смещением позиции.
Чтобы загрузить голограммы из предыдущих сеансов, выполните указанные ниже действия.
WorldAnchorStoreПолучите .
Загрузите данные приложения привязок мира, чтобы получить идентификатор мировой привязки.
Загрузка привязки world по идентификатору.
Чтобы сохранить голограммы для будущих сеансов, выполните следующие действия.
WorldAnchorStoreПолучите .
Сохраните привязку world с указанием идентификатора.
Сохраните данные приложения, связанные с привязкой world вместе с идентификатором.
Получение WorldAnchorStore
Оставьте ссылку на WorldAnchorStore, чтобы знать, когда он будет готов к выполнению операции. Так как этот вызов является асинхронным, сразу после запуска приложения можно вызвать:
WorldAnchorStore.GetAsync(StoreLoaded);
StoreLoaded — это обработчик после WorldAnchorStore завершения загрузки:
Теперь у вас есть ссылка на WorldAnchorStore, которую можно использовать для сохранения и загрузки определенных мировых привязок.
Сохранение привязки к миру
Чтобы сохранить мировую привязку, присвойте ей имя и передайте ее в WorldAnchorStore ранее полученный. При попытке сохранить две привязки в одной строке возвращает store.Save значение false. Удалите предыдущее сохранение перед сохранением нового.
private void SaveGame()
{
// Save data about holograms that this world anchor positions
if (!this.savedRoot) // Only save the root once
{
this.savedRoot = this.store.Save("rootGameObject", anchor);
Assert(this.savedRoot);
}
}
Загрузка мировой привязки
Чтобы загрузить мировую привязку, выполните приведенные далее действия.
private void LoadGame()
{
// Saved data about holograms that this world anchor positions:
this.savedRoot = this.store.Load("rootGameObject", rootGameObject);
if (!this.savedRoot)
{
// Game root not saved. Re-place objects or start over.
}
}
Вы также можете использовать для store.Delete() удаления ранее сохраненной привязки, а store.Clear() также для удаления всех ранее сохраненных данных.
Перечисление существующих привязок
Чтобы получить список сохраненных привязок, вызовите GetAllIds.
string[] ids = this.store.GetAllIds();
for (int index = 0; index < ids.Length; index++)
{
Debug.Log(ids[index]);
}
Сохранение голограмм для нескольких устройств
Пространственные привязки Azure можно использовать для создания устойчивой облачной привязки из локальной мировой привязки. Приложение может находить облачную привязку на нескольких устройствах HoloLens, iOS и Android, даже если они не одновременно. Так как облачные привязки являются постоянными, несколько устройств могут видеть содержимое, отображаемое относительно этой привязки в одном физическом расположении с течением времени.
Дальнейшие действия
Совместное использование заблокированного пространства координат: