Локальная передача привязки в Unity
Локальная передача привязки позволяет одному устройству HoloLens экспортировать привязку, импортируемую вторым устройством HoloLens.
Примечание.
Устройства iOS и Android не поддерживаются этим подходом.
Настройка возможности SpatialPerception
Чтобы приложение передавало пространственные привязки, необходимо включить возможность SpatialPerception .
Как включить функцию SpatialPerception :
- В редакторе Unity откройте панель "Параметры проигрывателя" (изменение > проигрывателя параметров > проекта)
- Щелкните вкладку "Магазин Windows"
- Разверните раздел "Параметры публикации" и проверьте возможность "SpatialPerception" в списке "Возможности"
Примечание.
Если вы уже экспортировали проект Unity в решение Visual Studio, необходимо либо экспортировать в новую папку, либо вручную установить эту возможность в AppxManifest в Visual Studio.
Передача привязки
Пространство имен: UnityEngine.XR.WSA.Sharing
Тип: WorldAnchorTransferBatch
Чтобы передать WorldAnchor, необходимо установить привязку для передачи. Пользователь одного HoloLens сканирует свою среду, и вручную или программно выбирает точку в пространстве, чтобы быть привязкой для общего интерфейса. Затем данные, представляющие эту точку, можно сериализовать и передать на другие устройства, которые совместно используются в интерфейсе. Затем каждое устройство отменяет сериализацию данных привязки и пытается найти точку в пространстве. Чтобы передача привязки работала, каждое устройство должно быть проверено достаточно в среде, чтобы можно было определить точку, представленную привязкой.
Настройка
Пример кода на этой странице содержит несколько полей, которые необходимо инициализировать:
- GameObject rootGameObject — это GameObject в Unity с компонентом WorldAnchor. Один пользователь в общем интерфейсе будет размещать этот GameObject и экспортировать данные другим пользователям.
- WorldAnchor gameRootAnchor — это UnityEngine.XR.WSA.WorldAnchor, который находится в rootGameObject.
- byte[] importedData — это массив байтов для сериализованной привязки каждого клиента, получающего через сеть.
public GameObject rootGameObject;
private UnityEngine.XR.WSA.WorldAnchor gameRootAnchor;
void Start ()
{
gameRootAnchor = rootGameObject.GetComponent<UnityEngine.XR.WSA.WorldAnchor>();
if (gameRootAnchor == null)
{
gameRootAnchor = rootGameObject.AddComponent<UnityEngine.XR.WSA.WorldAnchor>();
}
}
Экспорт
Чтобы экспортировать, нам просто нужен WorldAnchor и знать, что мы будем называть его таким образом, что это имеет смысл для получения приложения. Один клиент в общем интерфейсе выполнит следующие действия для экспорта общей привязки:
- Создание WorldAnchorTransferBatch
- Добавление WorldAnchors для передачи
- Начало экспорта
- Обработка события OnExportDataAvailable по мере того, как данные становятся доступными
- Обработка события OnExportComplete
Мы создадим WorldAnchorTransferBatchch , чтобы инкапсулировать то, что мы передаем, а затем экспортируем их в байты:
private void ExportGameRootAnchor()
{
WorldAnchorTransferBatch transferBatch = new WorldAnchorTransferBatch();
transferBatch.AddWorldAnchor("gameRoot", this.gameRootAnchor);
WorldAnchorTransferBatch.ExportAsync(transferBatch, OnExportDataAvailable, OnExportComplete);
}
По мере того как данные становятся доступными, отправьте байты клиенту или буферу как сегменты данных доступны и отправляются с помощью любых необходимых средств:
private void OnExportDataAvailable(byte[] data)
{
TransferDataToClient(data);
}
После завершения экспорта, если мы переносим данные и сериализацию не удалось, сообщите клиенту отменить данные. Если сериализация выполнена успешно, сообщите клиенту, что все данные переданы и импортируются:
private void OnExportComplete(SerializationCompletionReason completionReason)
{
if (completionReason != SerializationCompletionReason.Succeeded)
{
SendExportFailedToClient();
}
else
{
SendExportSucceededToClient();
}
}
Импорт
Получив все байты от отправителя, мы можем импортировать данные обратно в WorldAnchorTransferBatch и заблокировать наш корневой игровой объект в том же физическом расположении. Примечание. Иногда импорт завершается временным сбоем и требуется выполнить повторную попытку:
// This byte array should have been updated over the network from TransferDataToClient
private byte[] importedData;
private int retryCount = 3;
private void ImportRootGameObject()
{
WorldAnchorTransferBatch.ImportAsync(importedData, OnImportComplete);
}
private void OnImportComplete(SerializationCompletionReason completionReason, WorldAnchorTransferBatch deserializedTransferBatch)
{
if (completionReason != SerializationCompletionReason.Succeeded)
{
Debug.Log("Failed to import: " + completionReason.ToString());
if (retryCount > 0)
{
retryCount--;
WorldAnchorTransferBatch.ImportAsync(importedData, OnImportComplete);
}
return;
}
this.gameRootAnchor = deserializedTransferBatch.LockObject("gameRoot", this.rootGameObject);
}
После блокировки GameObject через вызов LockObject он будет иметь WorldAnchor, который будет хранить его в той же физической позиции в мире, но он может находиться в другом расположении в пространстве координат Unity, чем другие пользователи.