Блокировка мира и пространственные привязки в Unity
Статья
Получение голограмм, чтобы оставаться на месте, перемещаться с вами или в некоторых случаях позиционировать себя относительно других голограмм является большой частью создания Смешанная реальность приложений. В этой статье мы рассмотрим наше рекомендуемое решение с помощью средств всемирной блокировки, но мы также рассмотрим вручную настройку пространственных привязок в проектах Unity. Прежде чем перейти к любому коду, важно понять, как Unity обрабатывает пространство координат и привязки в собственном обработчике.
Системы координат мирового масштаба
Сегодня при написании игр, приложений визуализации данных или приложений виртуальной реальности типичный подход заключается в создании одной абсолютной системы координат мира, с которыми можно надежно сопоставить все остальные координаты. В этой среде всегда можно найти стабильное преобразование, определяющее связь между любыми двумя объектами в этом мире. Если эти объекты не были перемещены, их относительные преобразования всегда останутся неизменными. Такая глобальная система координат легко получить право при отрисовке чисто виртуального мира, где вы знаете все геометрии заранее. Приложения виртуальной реальности в масштабе помещений сегодня обычно устанавливают такую абсолютную систему координат в масштабе помещений с его источником на полу.
В отличие от этого, устройство смешанной реальности, например HoloLens, имеет динамическое понимание мира на основе датчика, постоянно корректируя свои знания в течение времени окружения пользователя, как они ходят по всему полу здания. Если вы помещаете все голограммы в наивную жесткую систему координат, эти голограммы будут в конечном итоге дрейфовать с течением времени, либо на основе мира или относительно друг друга.
Например, гарнитура в настоящее время может поверить в два расположения в мире, чтобы быть 4 метра друг от друга, а затем уточнить это понимание, научившись, что расположения на самом деле 3,9 метров друг от друга. Если эти голограммы изначально были размещены 4 метра друг от друга в одной жесткой системе координат, то один из них всегда будет отображаться 0,1 метра от реального мира.
Вы можете вручную разместить пространственные привязки в Unity, чтобы сохранить положение голограммы в физическом мире, когда пользователь является мобильным. Однако это жертвует самосогласованием в виртуальном мире. Различные привязки постоянно движутся по отношению друг к другу, а также перемещаются через глобальное пространство координат. В этом сценарии простые задачи, такие как макет, становятся сложными. Моделирование физики также может быть проблематичным.
Средства блокировки мира (WLT) получают лучшие из обоих миров, стабилизируя одну жесткую систему координат с помощью внутреннего предложения пространственных привязок, распространяемых по всей виртуальной сцене, когда пользователь перемещается вокруг. WLT анализирует координаты камеры и эти пространственные привязки каждого кадра. Вместо того, чтобы изменить координаты всего в мире, чтобы компенсировать исправления в координатах головы пользователя, WLT просто исправляет координаты головы.
Выбор подхода к блокировке мира
По возможности используйте средства блокировки мира для размещения голограммы.
Средства блокировки мира обеспечивают стабильную систему координат, которая сводит к минимуму видимые несоответствия между виртуальными и реальными маркерами. World Locking Tools world-locks весь сцены с общим пулом якорей, а не блокировать каждую группу объектов с собственной отдельной привязкой группы.
Средства блокировки мира автоматически обрабатывают внутреннее создание и управление пространственными привязками. Вам не нужно взаимодействовать с ARAnchorManager или WorldAnchor, чтобы держать голограммы заблокированными в мире.
Для Unity 2019/2020 с помощью OpenXR или подключаемого модуля Windows XR используйте ARAnchorManager.
Для более старых версий Unity или проектов WSA используйте WorldAnchor.
Чтобы приступить к работе с средствами блокировки мира, скачайте средство Смешанная реальность компонентов. Дополнительные сведения об основах см. на главной странице документации по средствам блокировки мира для ссылок на обзор, краткое руководство и другие полезные разделы.
Когда проект будет готов к работе, запустите программу настройки сцены из Смешанная реальность > World Locking Tools:
Внимание
Программу Configure scene можно повторно запустить в любое время. Например, ее следует запустить повторно, если целевой объект AR был изменен с Legacy на XR SDK. Если сцена уже настроена правильно, запуск программы ничего не изменит.
Визуализаторы
Во время ранней разработки добавление визуализаторов может быть полезным для обеспечения правильной настройки WLT и правильной работы. Их можно удалить с помощью программы Remove visualizers для повышения производительности или если они больше не нужны. Дополнительные сведения о визуализаторах можно найти в документации по средствам.
Подключаемый модуль OpenXR Смешанная реальность предоставляет базовые функции привязки через реализацию ARFoundation ARAnchorManager Unity. Чтобы узнать основы ARAnchors в ARFoundation, посетите руководство ARFoundation для AR Anchor Manager.
Пространство имен:UnityEngine.XR.WSA Тип:WorldAnchor
Этот игровой объект теперь привязан к текущему расположению в физическом мире. Возможно, с течением времени координаты мира Unity немного изменяются, чтобы обеспечить физическое выравнивание. См . загрузку привязки мира , чтобы снова найти это привязанное расположение в будущем сеансе приложения.
Удаление привязки мира
Если вы больше не хотите GameObject , чтобы заблокированное расположение физического мира и не планируете перемещать его этот кадр, вызовите Destroy компонент World Anchor.
Destroy(gameObject.GetComponent<WorldAnchor>());
Если вы хотите переместить GameObject этот кадр, вызовите DestroyImmediate его.
Вы не можете переместить некоторое GameObject время мировой привязки на нем. Если вам нужно переместить GameObject этот кадр, необходимо выполнить следующие действия.
DestroyImmediate Компонент World Anchor.
GameObjectПеремещение .
Добавьте новый компонент World Anchor в объект GameObject.
Мировая привязка может быть неуловимой в физическом мире в определенный момент времени. Затем Unity не обновит преобразование привязанного объекта. Эта ситуация также может произойти во время работы приложения. Сбой обработки изменения в неуправляемости приводит к тому, что объект не отображается в правильном физическом расположении в мире.
Чтобы получать уведомления об изменениях в области доступности:
Подпишитесь на OnTrackingChanged событие. Событие OnTrackingChanged вызывается всякий раз, когда базовый пространственный привязка изменяется между состоянием неуправляемого или не является неуправляемым.
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 свойство привязки присваивается true при AddComponent<WorldAnchor>() возврате. OnTrackingChanged Поэтому событие не активируется. Более чистый шаблон — вызвать OnTrackingChanged обработчик с начальным IsLocated состоянием после присоединения привязки.
Пространственные привязки сохраняют голограммы в реальном пространстве между сеансами приложений. После сохранения в хранилище привязки HoloLens пространственные привязки можно найти и загрузить в разных сеансах и являются идеальным резервным вариантом, когда нет подключения к Интернету.
Внимание
Локальные привязки хранятся на устройстве, а пространственные привязки Azure сохраняются в облаке. Локальные и привязки Azure можно использовать в одном проекте без конфликтов. Дополнительные сведения об интеграции облачных служб Azure для хранения привязок см. в статье "Пространственные привязки Azure".
По умолчанию world Locking Tools восстанавливает систему координат Unity относительно физического мира между сеансами на устройствах, поддерживающих сохраняемость локальных пространственных привязок. Чтобы голограмма отображалась в том же месте в физическом мире после выхода и повторного запуска приложения, приложение должно восстановить ту же позу в голограмме.
Если приложению требуется более точное управление, вы можете отключить автоматическое сохранение и автоматическую загрузку в инспекторе и управлять сохраняемостью из скрипта. Дополнительные сведения см. в разделе "Сохранение систем пространственной координаты".
Средства блокировки мира поддерживают сохраняемость локальных привязок только на устройствах HoloLens. Для устройств Android, iOS и HoloLens интегрируются с пространственными привязками Azure для поддержки сохраняемости и совместного использования пространств координат между сеансами и устройствами. Дополнительные сведения и примеры использования средств блокировки мира с пространственными привязками Azure см. в статье "Средства блокировки мира" (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 следующим образом:
Чтобы просмотреть полный пример сохранения и отмены привязки, ознакомьтесь со скриптом "Привязки "> Пример 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Получите .
Загрузка данных приложения привязки мира, которая предоставляет идентификатор привязки мира.
Загрузите привязку мира по идентификатору.
Чтобы сохранить голограммы для будущих сеансов, выполните следующее:
WorldAnchorStoreПолучите .
Сохраните привязку мира, указав идентификатор.
Сохраните данные приложения, связанные с привязкой мира вместе с идентификатором.
Получение 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, даже если устройства не находятся вместе одновременно. Так как облачные привязки являются постоянными, с течением времени несколько устройств могут просматривать содержимое, отображаемое относительно этой привязки в одном физическом расположении.
Следующие шаги
Совместное использование заблокированного пространства координат: