Системы координат в Unity

Windows Mixed Reality поддерживает приложения в самых разных масштабах: от приложений с ориентацией и с размещением до приложений для масштабирования помещений. В HoloLens вы можете идти дальше и создавать приложения мирового масштаба, которые позволяют пользователям ходить за пределы 5 метров, исследуя весь этаж здания и за его пределами.

Первым шагом в создании смешанной реальности в Unity является понимание систем координат и выбор масштабирования, предназначенного для вашего приложения.

Создание интерфейса только для ориентации или масштабирования с сидячим местом

Пространство имен:UnityEngine.XR
Тип:XRDevice

Чтобы создать интерфейс только для ориентации или сидячих мест, необходимо задать для Unity тип пространства для отслеживания стационарных данных. Неподвижное пространство отслеживания задает мировую систему координат Unity для отслеживания неподвижной системы отсчета. В режиме стационарного отслеживания содержимое, размещенное в редакторе непосредственно перед расположением камеры по умолчанию (вперед — -Z), будет отображаться перед пользователем при запуске приложения.

XRDevice.SetTrackingSpaceType(TrackingSpaceType.Stationary);

Пространство имен:UnityEngine.XR
Тип:InputTracking

Для чистой ориентации, например 360-градусного видеозрителя (где обновления позиционной головы разрушают иллюзию), можно установить XR. InputTracking.disablePositionalTracking до true:

InputTracking.disablePositionalTracking = true;

Для масштабирования с помощью сидячего места можно вызвать XR, чтобы позволить пользователю позже переначертить источник места. Метод InputTracking.Recenter :

InputTracking.Recenter();

Создание постоянного или комнатного интерфейса

Пространство имен:UnityEngine.XR
Тип:XRDevice

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

Чтобы убедиться, что Unity работает с мировой системой координат на уровне пола, можно задать и проверить, использует ли Unity тип пространства отслеживания RoomScale:

if (XRDevice.SetTrackingSpaceType(TrackingSpaceType.RoomScale))
{
    // RoomScale mode was set successfully.  App can now assume that y=0 in Unity world coordinate represents the floor.
}
else
{
    // RoomScale mode was not set successfully.  App cannot make assumptions about where the floor plane is.
}
  • Если SetTrackingSpaceType возвращает значение true, Unity успешно переключила свою систему координат мира для отслеживания сценической системы отсчета.
  • Если SetTrackingSpaceType возвращает значение false, Unity не удалось переключиться на промежуточную систему отсчета, скорее всего, из-за того, что пользователь не настроил пол в своей среде. Хотя ложное возвращаемое значение не является общим, это может произойти, если этап настроен в другой комнате и устройство перемещено в текущую комнату без настройки пользователем нового этапа.

Когда приложение успешно задаст тип пространства для отслеживания RoomScale, содержимое, размещенное в плоскости y=0, будет отображаться на полу. Источником в 0, 0, 0 будет конкретное место на полу, где пользователь стоял во время настройки комнаты, а -Z представляет направление вперед, к которому он столкнулся во время установки.

Пространство имен:UnityEngine.Experimental.XR
Тип:граница

Затем в коде скрипта можно вызвать метод TryGetGeometry для типа UnityEngine.Experimental.XR.Boundary, чтобы получить пограничный многоугольник, указав тип границы TrackedArea. Если пользователь определил границу (вы получите список вершин), можно с уверенностью предоставить пользователю возможность масштабирования комнаты , где он сможет обойти созданную сцену.

Примечание

Система автоматически отрисовывает границу, когда пользователь приближается к ней. Приложению не нужно использовать этот многоугольник для отрисовки самой границы. Однако вы можете разместить объекты сцены с помощью этого пограничного многоугольника, чтобы пользователь мог физически связаться с этими объектами без телепортирования:

var vertices = new List<Vector3>();
if (UnityEngine.Experimental.XR.Boundary.TryGetGeometry(vertices, Boundary.Type.TrackedArea))
{
    // Lay out your app's content within the boundary polygon, to ensure that users can reach it without teleporting.
}

Создание интерфейса мирового масштаба

Пространство имен:UnityEngine.XR.WSA
Тип:WorldAnchor

Для истинного мирового уровня взаимодействия с HoloLens, который позволяет пользователям бродить за пределы 5 метров, вам потребуются новые методы, помимо тех, которые используются для масштабирования помещений. Один из ключевых способов, который вы будете использовать, заключается в создании пространственной привязки для блокировки кластера голограмм точно на месте в физическом мире, независимо от того, насколько далеко пользователь перемещается, а затем найти эти голограммы снова в последующих сеансах.

В Unity можно создать пространственную привязку, добавив компонент WorldAnchor Unity в GameObject.

Добавление всемирной привязки

Чтобы добавить привязку к миру, вызовите метод AddComponent<WorldAnchor>() в игровом объекте с преобразованием, которое вы хотите привязать в реальном мире.

WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

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

Удаление всемирной привязки

Если вы больше не хотите, чтобы GameObject был заблокирован в физическом мире и не планируете перемещать его этот кадр, можно просто вызвать Destroy в компоненте World Anchor.

Destroy(gameObject.GetComponent<WorldAnchor>());

Если вы хотите переместить gameObject этого кадра, необходимо вызвать DestroyImmediate.

DestroyImmediate(gameObject.GetComponent<WorldAnchor>());

Перемещение world anchored GameObject

GameObject нельзя переместить, пока на нем находится World Anchor. Если необходимо переместить gameObject этого кадра, вам потребуется:

  1. DestroyImmediate the World Anchor component
  2. Перемещение GameObject
  3. Добавьте новый компонент World Anchor в GameObject.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();

Обработка изменений locatability

WorldAnchor может быть недоступен в физическом мире в определенный момент времени. В этом случае Unity не будет обновлять преобразование привязанного объекта. Это также может измениться во время работы приложения. Неспособность обработать изменение locatability приведет к тому, что объект не будет отображаться в правильном физическом расположении в мире.

Чтобы получать уведомления об изменениях locatability, выполните приведенные далее действия.

  1. Подписка на событие OnTrackingChanged
  2. Обработка события

Событие OnTrackingChanged будет вызываться всякий раз, когда базовая пространственная привязка изменяется между состоянием locatable и not locatable.

anchor.OnTrackingChanged += Anchor_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 после присоединения привязки.

Anchor_OnTrackingChanged(anchor, anchor.isLocated);

Совместное использование привязок на разных устройствах

Используйте Пространственные привязки Azure , чтобы создать устойчивую облачную привязку из локального объекта WorldAnchor, которую приложение затем сможет найти на нескольких устройствах HoloLens, iOS и Android. Благодаря совместному использованию общей пространственной привязки на нескольких устройствах каждый пользователь может видеть содержимое, отображаемое относительно этой привязки, в одном физическом расположении. Это позволяет обмениваться опытом в режиме реального времени.

Чтобы приступить к созданию общих возможностей в Unity, ознакомьтесь с краткими руководствами по 5-минутным пространственным привязкам Azure для Unity.

После запуска пространственных привязок Azure можно создавать и находить привязки в Unity.

Следующий этап разработки

Если вы следуете описанной нами контрольной точке разработки в Unity, вы находитесь в разгар изучения Смешанная реальность основных стандартных блоков. Отсюда вы можете перейти к следующему стандартному блоку:

Или перейдите к возможностям и API платформы смешанной реальности:

Вы можете в любой момент вернуться к этапам разработки для Unity.

См. также: