Přenosy místních ukotvení v Unity
V situacích, kdy nemůžete použít Azure Spatial Anchors, místní přenosy ukotvení umožňují jednomu zařízení HoloLens exportovat ukotvení, které se má importovat pomocí druhého zařízení HoloLens.
Poznámka:
Přenosy místních ukotvení poskytují méně robustní odvolání ukotvení než Azure Spatial Anchors a zařízení s iOSem a Androidem nejsou tímto přístupem podporovány.
Nastavení funkce SpatialPerception
Aby aplikace mohla přenášet prostorové kotvy, musí být povolená funkce SpatialPerception .
Jak povolit funkci SpatialPerception :
- V Unity Editoru otevřete podokno Nastavení přehrávače (Upravit > přehrávač nastavení > projektu)
- Klikněte na kartu Windows Store .
- Rozbalte položku Nastavení publikování a v seznamu Možnosti zkontrolujte možnost SpatialPerception.
Poznámka:
Pokud jste projekt Unity už exportovali do řešení sady Visual Studio, budete muset buď exportovat do nové složky, nebo tuto funkci v sadě Visual Studio nastavit ručně.
Přenos ukotvení
Obor názvů: UnityEngine.XR.WSA.Sharing
Typ: WorldAnchorTransferBatch
Chcete-li přenést WorldAnchor, je nutné vytvořit kotvu, která má být přenesena. Uživatel jednoho HoloLens prohledá své prostředí a buď ručně, nebo programově zvolí bod v prostoru, který bude ukotven pro sdílené prostředí. Data, která představují tento bod, je pak možné serializovat a přenášet do ostatních zařízení, která sdílejí v prostředí. Každé zařízení pak de-serializuje data ukotvení a pokusí se najít tento bod v prostoru. Aby mohl přenos ukotvení fungovat, musí každé zařízení zkontrolovat v dostatečném množství prostředí, aby bylo možné identifikovat bod reprezentovaný ukotvením.
Nastavení
Vzorový kód na této stránce obsahuje několik polí, která bude potřeba inicializovat:
- GameObject rootGameObject je GameObject v Unity, který má komponentu WorldAnchor . Jeden uživatel ve sdíleném prostředí umístí tento Objekt GameObject a exportuje data ostatním uživatelům.
- WorldAnchor gameRootAnchor je UnityEngine.XR.WSA.WorldAnchor, který je na rootGameObject.
- byte[] importData je bajtové pole pro serializované ukotvení, které každý klient přijímá přes síť.
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>();
}
}
Exportování
Abychom mohli exportovat, potřebujeme jenom WorldAnchor a vědět, co mu budeme říkat, aby bylo pro přijímající aplikaci vhodné. Jeden klient ve sdíleném prostředí provede tento postup pro export sdíleného ukotvení:
- Vytvoření WorldAnchorTransferBatch
- Přidání WorldAnchors k převodu
- Zahájení exportu
- Zpracování události OnExportDataAvailable při zpřístupnění dat
- Zpracování události OnExportComplete
Vytvoříme WorldAnchorTransferBatch pro zapouzdření toho, co budeme přenášet a pak exportovat do bajtů:
private void ExportGameRootAnchor()
{
WorldAnchorTransferBatch transferBatch = new WorldAnchorTransferBatch();
transferBatch.AddWorldAnchor("gameRoot", this.gameRootAnchor);
WorldAnchorTransferBatch.ExportAsync(transferBatch, OnExportDataAvailable, OnExportComplete);
}
Jakmile budou data dostupná, posílejte bajty klientovi nebo vyrovnávací paměti, protože jsou k dispozici segmenty dat, a odešlete je libovolným způsobem:
private void OnExportDataAvailable(byte[] data)
{
TransferDataToClient(data);
}
Po dokončení exportu, pokud jsme přenesli data a serializace selhala, řekněte klientovi, aby data zahodil. Pokud serializace proběhla úspěšně, sdělte klientovi, že byla přenesena všechna data a import může začít:
private void OnExportComplete(SerializationCompletionReason completionReason)
{
if (completionReason != SerializationCompletionReason.Succeeded)
{
SendExportFailedToClient();
}
else
{
SendExportSucceededToClient();
}
}
Import
Po přijetí všech bajtů od odesílatele můžeme importovat data zpět do WorldAnchorTransferBatch a uzamknout kořenový herní objekt do stejného fyzického umístění. Poznámka: Import někdy selhává a je potřeba ho opakovat:
// 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);
}
Jakmile je Objekt GameObject uzamčen prostřednictvím volání LockObject, bude mít WorldAnchor, který ho bude udržovat ve stejné fyzické pozici na světě, ale může být na jiném místě v souřadnicovém prostoru Unity než ostatní uživatelé.