持続性
空間マッピング

アンカーの共有

アンカーの共有は World Anchor を 1 つのデバイスに保存するシステムで、他のデバイス上でもアンカーを読み込むことができます。

例えば、2 人のユーザーがテーブル上の仮想ゲームボードでゲームをしています。ユーザー同士がゲームボードにきちんと向かい合うためには、現実世界上のどこに仮想ゲームボードが置かれているかを両方のデバイスが空間的に把握する必要があります。アンカーを共有すると、アンカー情報を 1 人のユーザーのデバイスで保存し、他のユーザーのデバイスに反映することができます。

アンカー共有の機能には、デバイス間のデータを転送するためのトランスポート層が含まれているわけではありません。ネットワークのトランスポートシステムがこの機能を提供します。詳しくは Unity マニュアルの ネットワーキング を参照してください。

アンカーのエクスポート

既存の World Anchor をエクスポートするには、そのアンカーの共通の名前と WorldAnchorTransferBatch が必要です。

下ではこの API の基本的な使用例を示しています。以下の点に注意してください。

  1. OnExportDataAvailable へ複数回の呼び出しが発生します。
  2. アプリケーションから他のデバイスへインクリメントにデータ送信を行う設定の場合は、データを送信しても、エクスポートの呼び出しがストリーミングの途中で失敗するケースに対する処理も必用です。
private void ExportWorldAnchor()
{
    WorldAnchorTransferBatch transferBatch = new WorldAnchorTransferBatch();
    transferBatch.AddWorldAnchor("GameRootAnchor", this.MyWorldAnchor);
    WorldAnchorTransferBatch.ExportAsync(transferBatch, OnExportDataAvailable, OnExportComplete);
}

private void OnExportComplete(SerializationCompletionReason completionReason)
{
    if (completionReason != SerializationCompletionReason.Succeeded)
    {
        // データを転送しても失敗する場合は、 
        // クライアントにそのデータを破棄するよう伝えます
        SendExportFailedToClient();
    }
    else
    {
        // クライアントにシリアライズが成功したことを伝えます
        // クライアントは、すべてのデータの受信後にインポートを開始できます
        SendExportSucceededToClient();
    }
}

private void OnExportDataAvailable(byte[] data)
{
    // バイトをクライアントに送信します。データは、バッファリングされる場合もあります。
    TransferDataToClient(data); 
}

アンカーのインポート

データを受信したら、WorldAnchorTransferBatch を使ってインポートし、 World Anchor を他のクライアントで再作成します。

下ではこの API の基本的な使用例を示しています。インポートに失敗したら、処理を再試行してください。

private int retryCount = 10;
private void ImportWorldAnchor(byte[] importedData)
{
    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(fileData, OnImportComplete);
        }
        return;
    }
​
    string[] ids = deserializedTransferBatch.GetAllIds();
    foreach (string id in ids)
    {
        GameObject gameObject = GetGameObjectFromAnchorId(id);
        if (gameObject != null)
        {
            transferBatch.LockObject(id, gameObject);
        }
        else
        {
            Debug.Log("Failed to find object for anchor id: " + id);
        }
    }
}
持続性
空間マッピング