Lokalne transfery zakotwiczenia w a unity
Transfery zakotwiczeń lokalnych umożliwiają jednemu urządzeniu HoloLens eksportowanie kotwicy do zaimportowania przez drugie urządzenie HoloLens.
Uwaga
Takie podejście nie jest obsługiwane na urządzeniach z systemami iOS i Android.
Ustawianie możliwości SpatialPerception
Aby aplikacja przesyłała kotwice przestrzenne, należy włączyć funkcję SpatialPerception .
Jak włączyć funkcję SpatialPerception :
- W Edytorze aparatu Unity otwórz okienko "Ustawienia odtwarzacza" (Edytuj > odtwarzacz ustawień > projektu)
- Kliknij kartę "Sklep Windows"
- Rozwiń pozycję "Ustawienia publikowania" i sprawdź możliwości "SpatialPerception" na liście "Możliwości"
Uwaga
Jeśli projekt aparatu Unity został już wyeksportowany do rozwiązania programu Visual Studio, musisz wyeksportować go do nowego folderu lub ręcznie ustawić tę funkcję w programie AppxManifest w programie Visual Studio.
Transfer zakotwiczenia
Przestrzeń nazw: UnityEngine.XR.WSA.Sharing
Typ: WorldAnchorTransferBatch
Aby przenieść WorldAnchor, należy ustanowić kotwicę, która ma zostać przeniesiona. Użytkownik jednego urządzenia HoloLens skanuje swoje środowisko i ręcznie lub programowo wybiera punkt w przestrzeni jako kotwicę dla środowiska udostępnionego. Dane reprezentujące ten punkt można następnie serializować i przesyłać do innych urządzeń, które udostępniają środowisko. Każde urządzenie następnie usuwa serializację danych kotwicy i próbuje zlokalizować ten punkt w przestrzeni. Aby transfer kotwicy działał, każde urządzenie musi skanować wystarczająco dużo środowiska, aby można było zidentyfikować punkt reprezentowany przez kotwicę.
Ustawienia
Przykładowy kod na tej stronie zawiera kilka pól, które należy zainicjować:
- GameObject rootGameObject jest obiektem GameObject w środowisku Unity, który ma na nim składnik WorldAnchor. Jeden użytkownik w środowisku udostępnionym umieści ten obiekt GameObject i wyeksportuje dane do innych użytkowników.
- WorldAnchor gameRootAnchor to UnityEngine.XR.WSA.WorldAnchor, który znajduje się w obiekcie rootGameObject.
- byte[] importData to tablica bajtów dla serializowanej kotwicy odbieranej przez sieć.
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>();
}
}
Eksportujących
Aby wyeksportować, potrzebujemy tylko worldanchor i wiedzieć, co nazwamy tak, aby miało sens dla odbierającej aplikacji. Jeden klient w środowisku udostępnionym wykona następujące kroki, aby wyeksportować udostępnioną kotwicę:
- Tworzenie elementu WorldAnchorTransferBatch
- Dodawanie modułów WorldAnchors do transferu
- Rozpoczynanie eksportu
- Obsługa zdarzenia OnExportDataAvailable w miarę dostępności danych
- Obsługa zdarzenia OnExportComplete
Utworzymy element WorldAnchorTransferBatch , aby hermetyzować dane przesyłane, a następnie wyeksportować je do bajtów:
private void ExportGameRootAnchor()
{
WorldAnchorTransferBatch transferBatch = new WorldAnchorTransferBatch();
transferBatch.AddWorldAnchor("gameRoot", this.gameRootAnchor);
WorldAnchorTransferBatch.ExportAsync(transferBatch, OnExportDataAvailable, OnExportComplete);
}
Gdy dane staną się dostępne, wyślij bajty do klienta lub buforu, ponieważ segmenty danych są dostępne i wysyłane za pośrednictwem dowolnych środków:
private void OnExportDataAvailable(byte[] data)
{
TransferDataToClient(data);
}
Po zakończeniu eksportowania, jeśli transfer danych i serializacji zakończył się niepowodzeniem, poinformuj klienta o odrzuceniu danych. Jeśli serializacja zakończyła się pomyślnie, poinformuj klienta, że wszystkie dane zostały przesłane i zaimportowane mogą rozpocząć się:
private void OnExportComplete(SerializationCompletionReason completionReason)
{
if (completionReason != SerializationCompletionReason.Succeeded)
{
SendExportFailedToClient();
}
else
{
SendExportSucceededToClient();
}
}
Importowanie
Po otrzymaniu wszystkich bajtów od nadawcy możemy zaimportować dane z powrotem do obiektu WorldAnchorTransferBatch i zablokować nasz obiekt gry głównej w tej samej lokalizacji fizycznej. Uwaga: importowanie czasami kończy się przejściowym niepowodzeniem i należy ponowić próbę:
// 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);
}
Po zablokowaniu obiektu GameObject za pośrednictwem wywołania LockObject będzie on miał obiekt WorldAnchor, który zachowa go w tej samej pozycji fizycznej na świecie, ale może znajdować się w innej lokalizacji w przestrzeni współrzędnej aparatu Unity niż inni użytkownicy.