Sdílet prostřednictvím


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 :

  1. V Unity Editoru otevřete podokno Nastavení přehrávače (Upravit > přehrávač nastavení > projektu)
  2. Klikněte na kartu Windows Store .
  3. 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:

  1. 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.
  2. WorldAnchor gameRootAnchor je UnityEngine.XR.WSA.WorldAnchor, který je na rootGameObject.
  3. 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í:

  1. Vytvoření WorldAnchorTransferBatch
  2. Přidání WorldAnchors k převodu
  3. Zahájení exportu
  4. Zpracování události OnExportDataAvailable při zpřístupnění dat
  5. 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é.