共有空間アンカー 更新日時: 2026/10/07
共有空間アンカー(SSA)機能を使えば、同じ物理スペースにいるプレイヤーが同じゲームをする間、コンテンツを共有することができます。SSAにより、多くのユーザーが参照するための共有ワールドロックフレームを作ることができます。例えば、2人以上で同じテーブルに座って、その上でバーチャルボードゲームをプレイすることができます。現在SSAでは、単一ルームでのローカルマルチプレイヤーゲームがサポートされています。
後出の
SSAのしくみ のセクションでは、SSAがマルチプレイヤー対応アプリにどうフィットするかについて説明しています。
このページを読むと、以下のことができるようになります。
マルチプレイヤー環境における共有空間アンカーの機能について説明する。 共有空間アンカー用にアプリを設定する手順について説明する。 OVRSpatialAnchorのメソッドを使った空間アンカーの作成、保存、共有、読み込みの処理を定義する。 グループベースとユーザーベースでの空間アンカーの共有と読み込み 現在のv71では、空間アンカーの共有と読み込みはユーザーではなくグループに基づいて行われます。
アンカーの共有と読み込みに関するグループベースとユーザーベースの主な違いをいくつか紹介します。
任意のグループUUIDを使ってアンカーの共有と読み込みを行う方法 ユーザーベースの共有と比べて前提条件が少ない v71以降でサポート アンカーの共有と読み込みに関して推奨されるアプローチ OculusユーザーIDを使用して、特定のユーザーとアンカーを共有し、読み込む方法 ユーザーIDへのアクセスとユーザープロフィールのデータアクセス許可をリクエストするため、Questストアアプリを作成することが必要 グループベースのバージョンに比べて前提条件が多い Unityの開発の場合、どちらのアプローチでも、OVRSpatialAnchor.SaveAnchorAsync()を通じて空間アンカーを保存した後、それを共有するためにOVRSpatialAnchor.ShareAsync()のバリエーションを利用しています。
グループIDまたは一連のユーザーとの共有に成功したアンカーは、OVRSpatialAnchor.LoadUnboundSharedAnchorsAsync()のバリエーションを呼び出すことにより、各共有相手が読み込めるようになります。
SSAが別のユーザーによって読み込まれると、そのユーザーのデバイス上にダウンロードされます。その時点では、元の空間アンカーのローカルコピーのように動作します。アンカーインスタンスを破棄しても、共有されているアンカーに影響はなく、将来もう一度アクセスする際のユーザーのアクセス許可が変更されることもありません。
public static OVRTask<OVRResult<OVRAnchor.ShareResult>> ShareAsync(IEnumerable<OVRSpatialAnchor> anchors, Guid groupUuid);
public static OVRTask<OVRResult<OVRAnchor.ShareResult>> ShareAsync(IEnumerable<OVRSpatialAnchor> anchors, IEnumerable<Guid> groupUuids);
public static OVRTask<OVRResult<List<UnboundAnchor>, OperationResult>> LoadUnboundSharedAnchorsAsync(Guid groupUuid, List<UnboundAnchor> unboundAnchors)
グループベースの空間アンカーの共有と読み込みを開始する Use the Colocation building block for Colocation Discovery
v74以降では、[Use Colocation Session (コロケーションセッションを使う)]オプションを指定してコロケーションビルディングブロック を使用することで、コロケーション発見を有効にできます。この方法では、Colocation Discovery APIやGroup Sharing APIを使って、マッチメイクやアンカー共有など、プレイヤー間のネットワーク通信を容易にします。 Meta Quest 2、Quest Pro、Quest 3、Quest 3S、またはMeta VR Glasses Meta XR Core SDK v71以降が実行されていることMeta Questデバイスで拡張空間サービスをオンにするには、[Settings (設定)] > [Privacy and Safety (プライバシーと安全性)] > [Device Permissions (デバイスアクセス許可)] に進み、[Enhanced Spatial Services (拡張空間サービス)] を選択してください。
アプリでは、この設定が無効にされていることを検出し、ユーザーに有効にするよう通知することができます。ユーザーが拡張空間サービスを有効にしていない場合は、データを共有したり(ShareAsync)、他のユーザーが読み込もうとしたりすると(LoadSharedAnchorsAsync)、アプリはエラーコードOVRSpatialAnchor.OperationResult.Failure_SpaceCloudStorageDisabledを受け取ります。
OVRCameraRigで[Unity Inspector (Unityインスペクター)]に移動し、[OVRManager’s Quest Features (OVRManagerのQuest機能)]セクションで、
[Shared Spatial Anchors (共有空間アンカー)] と
[Passthrough (パススルー)] を有効にします。
別の方法: Androidマニフェストを使ってアクセス許可を追加する OVRManagerを使ってアクセス許可を有効にする代わりに、Androidマニフェストを通じてアクセス許可を追加することにより、共有空間アンカーを有効にすることもできます。
Unity EditorでSSAをサポートするようにプロジェクトマニフェストを更新するには、[Window (ウィンドウ)] > [Meta] > [Tools (ツール)] に移動し、[Create store-compatible AndroidManifest.xml (ストア互換のAndroidManifest.xmlを作成)] を選択します。
SSAとパススルーが機能するには、以下のアクセス許可が必要です。
<uses-permission android:name="com.oculus.permission.USE_ANCHOR_API" /><uses-permission android:name="com.oculus.permission.IMPORT_EXPORT_IOT_MAP_DATA" android:required="false" /><uses-feature android:name="com.oculus.feature.PASSTHROUGH" android:required="true" /> グループベースの共有では、以下の2つの点でアプリのロジックが簡略化されます。
空間アンカーを共有するプレイヤーは、共有相手のユーザーIDをトラッキングする必要がありません。代わりに、すべてのクライアントが参照できる固有のグループIDを通じて共有できます。 グループIDを使って、グループに共有されているすべてのアンカーについて問い合わせることができるため、読み込むアンカーIDのリストを維持する必要がありません。 SSAをグループと共有する前に、参加者のうちの1人が、グループを表す単一のUUIDを作成し、他の参加者に伝える必要があります。そのための通信手段としては、アプリで管理するネットワーク接続か、
コロケーション発見 のいずれかが可能です。後者を使えば、コロケーションエクスペリエンスの設定に関係したエンドユーザーの面倒な作業を大幅に軽減できます。グループIDが作成されて伝播された後、プレイヤーが以前に保存した空間アンカーを共有したい場合、次の呼び出しを行います。
// Share multiple anchors with a group
public static OVRTask<OperationResult> ShareAsync(
IEnumerable<OVRSpatialAnchor> anchors,
Guid groupUuid);
次に共有相手が以下のメソッドを呼び出すことによって、このグループで共有されているすべての空間アンカーを読み込みます。
public static OVRTask<OVRResult<List<UnboundAnchor>, OperationResult>> LoadUnboundSharedAnchorsAsync(
Guid groupUuid,
List<UnboundAnchor> unboundAnchors)
こちら で説明されているように、未バインドの各アンカーを利用する前にローカライズする必要があります。
グループを使ってさらに多くのアンカーが共有された場合、アプリは、グループのアンカーを再読み込みする必要があることを各クライアントに伝える必要があります。ただし、個々のアンカーのIDを各クライアントに伝える必要はありません。
public OVRTask<OperationResult> ShareAsync(OVRSpaceUser user);
public OVRTask<OperationResult> ShareAsync(OVRSpaceUser user1, OVRSpaceUser user2);
public OVRTask<OperationResult> ShareAsync(OVRSpaceUser user1, OVRSpaceUser user2, OVRSpaceUser user3);
public OVRTask<OperationResult> ShareAsync(OVRSpaceUser user1, OVRSpaceUser user2, OVRSpaceUser user3, OVRSpaceUser user4);
public OVRTask<OperationResult> ShareAsync(IEnumerable<OVRSpaceUser> users);
public static OVRTask<OperationResult> ShareAsync(IEnumerable<OVRSpatialAnchor> anchors, IEnumerable<OVRSpaceUser> users);
public static OVRTask<OVRResult<List<UnboundAnchor>, OVRAnchor.FetchResult>> LoadUnboundAnchorsAsync(IEnumerable<Guid> uuids, List<UnboundAnchor> unboundAnchors, Action<List<UnboundAnchor>, int> onIncrementalResultsAvailable = null);
public static OVRTask<OVRResult<List<UnboundAnchor>, OperationResult>> LoadUnboundSharedAnchorsAsync(IEnumerable<Guid> uuids, List<UnboundAnchor> unboundAnchors)
Unity Editorで拡張空間サービスをオンにするには、[Settings (設定)] > [Privacy and Safety (プライバシーと安全性)] > [Device Permissions (デバイスアクセス許可)] に移動し、[Enhanced Spatial Services (拡張空間サービス)] を選択します。
アプリでは、この設定が無効にされていることを検出し、ユーザーに有効にするよう通知することができます。ユーザーが拡張空間サービスを有効にしていない場合は、データを共有したり(ShareAsync)、他のユーザーが読み込もうとしたりすると(LoadSharedAnchorsAsync)、アプリはエラーコードOVRSpatialAnchor.OperationResult.Failure_SpaceCloudStorageDisabledを受け取ります。
Unity Editorの[Hierarchy (階層)]で該当する
OVRCameraRig を選択した後、[Unity Inspector (Unityインスペクター)]に移動し、
OVRManager の
[Quest Features (Quest機能)] セクションの下で
[Shared Spatial Anchors (共有空間アンカー)] と
[Passthrough (パススルー)] を有効にします。
別の方法: Androidマニフェストを使ってアクセス許可を追加する OVRManagerを使ってアクセス許可を有効にする代わりに、Androidマニフェストを通じてアクセス許可を追加することにより、共有空間アンカーを有効にすることもできます。
Unity EditorでSSAをサポートするようにプロジェクトマニフェストを更新するには、[Window (ウィンドウ)] > [Meta] > [Tools (ツール)] に移動し、[Create store-compatible AndroidManifest.xml (ストア互換のAndroidManifest.xmlを作成)] を選択します。
SSAとパススルーが機能するには、以下のアクセス許可が必要です。
<uses-permission android:name="com.oculus.permission.USE_ANCHOR_API" /><uses-permission android:name="com.oculus.permission.IMPORT_EXPORT_IOT_MAP_DATA" android:required="false" /><uses-feature android:name="com.oculus.feature.PASSTHROUGH" android:required="true" /> さらに、開発中に共有空間アンカーが動作するようにするには、次のいずれかの条件を満たしている必要があります。
開発者が認証済み開発者チームのメンバーである。
開発者が、アプリを所有する開発者チームのテストユーザーである。
開発者が開発者チームによって、アプリの公開/本番リリースチャネル以外のリリースチャネルに招待されている。
[Data Use Checkup (データの使用状況の確認)] で[User ID (ユーザーID)] と[User Profile (ユーザープロフィール)] を有効にする注 : このセクションが必要になるのは、Oculus IDを使って空間アンカーを共有する場合だけです。グループUUIDを使って空間アンカーを共有する場合、このセクションは不要です。
アプリを作成する際、Meta Horizonストア を選択します。Linkを使ってPCからアプリを実行する場合は、これらの手順を繰り返してPCVRアプリも作成してください。
各アプリで
データ使用状況の確認 を完了する必要があります。空間アンカーを永続的なものにするためには、次のようにします。
アプリに対する管理者アクセス権をまだ取得していない場合は取得します。 Meta Horizon開発者ダッシュボード にログインします。アプリを選択します。 左側のナビゲーションで[Requirements (要件)] > [Data Use Checkup (データの使用状況の確認)] の順にクリックします。 [User ID (ユーザーID)] と[User Profile (ユーザープロフィール)] のプラットフォーム機能を追加してから、リクエストを送信します。空間アンカーを共有しようとするSSAクライアントにユーザーベースのアプローチを適用する場合は、特定のユーザーのapp-scoped user IDを指定します。このIDは、OculusPlatform.Users.GetLoggedInUserID() を通じて各クライアントに対して利用可能になります。さらに、共有する全アンカーの固有のIDを、すべての共有相手に伝える必要があります。アプリコードは、これらのユーザーIDとアンカーIDをすべての位置共有クライアントに伝える役割をします。
すべてのユーザーIDが共有元に伝えられたら、以下の呼び出しにより、以前に保存した空間アンカーを共有することができます。
// Share multiple anchors with a group
public static OVRTask<OperationResult> ShareAsync(
IEnumerable<OVRSpatialAnchor> anchors,
IEnumerable<OVRSpaceUser> users);
次に共有相手が以下のメソッドを呼び出すことによって、このグループで共有されているすべての空間アンカーを読み込みます。
public static OVRTask<OVRResult<List<UnboundAnchor>, OperationResult>> LoadUnboundSharedAnchorsAsync(
IEnumerable<Guid> uuids,
List<UnboundAnchor> unboundAnchors)
こちら で説明されているように、未バインドの各アンカーを利用する前にローカライズする必要があります。
さらに多くのユーザーが参加したり退出したりして多くのアンカーが共有された場合、アプリはこれらの変更についてすべてのクライアントに伝える必要があり、新しいアンカーが共有されたら各クライアントに通知する必要があります。
アプリにSSAを統合する処理の概要は、以下のとおりです。
ユーザーを相互につなぐため、ネットワークソリューションを使ってルームを作成します。メンバーシップ、アクティビティボード、または招待のいずれかによって、複数のユーザーが同じルームに参加するようにします。例えば、これを達成するには、Photonのマッチメイクとロビーの機能が役立ちます。 OVRSpatialAnchorコンポーネントが含まれるオブジェクトをインスタンス化することにより、アンカーを作成します。OVRSpatialAnchor.SaveAnchorAsync()を使ってアンカーを保存します。この呼び出しが完了するのを待ってから、アンカーを共有します。ルームの全プレイヤーに対してOVRSpatialAnchor.ShareAsync()を使うことにより、アンカーを一連のユーザーと共有します。この呼び出しが完了するとすぐに、他のプレイヤーがSSAを読み込むことができるようになります。 アンカーのUUIDを一斉送信します。例えば、ネットワーキングソリューションを使って、ルーム内のすべてのプレイヤーにSSAのUUIDを一斉送信します。 アンカーを読み込みます。これで各プレイヤーは、OVRSpatialAnchor.LoadUnboundSharedAnchorsAsync()を使って、上記ステップのUUIDによってアンカーを読み込むことができるようになります これで全プレイヤーが、アンカーを共有座標フレームまたは原点として使うことができるようになります。 空間アンカーを共有することで、そのポイントクラウドデータを共有し、どのユーザーIDまたはどのグループIDにその読み込みを許可するかを指定することになります。
注 : 利用しているネットワークソリューションに関係なく、空間アンカーの共有相手となるすべてのユーザーやグループは、アプリで拡張空間サービス を有効にしていなければなりません。それによりユーザーは、共有されるアンカーにアクセスできるようになります。
空間アンカーを共有する前に、まず保存する必要があります。OVRSpatialAnchorメソッドのSaveAnchorAsync()を使うことができます。このメソッドは非同期です。
ShareAsyncは、
awaitを実行したり、
ContinueWithを使ってコールバックを使用したりできる、待機可能なタスクに似たオブジェクトを返します。
Meta XR Core SDK でのタスクベースのプログラミングについて詳しくは、
非同期タスク をご覧ください。
タスクのOperationResultを使うことにより、共有が成功したかどうか、また失敗した場合にどんなアクションが必要かを調べることができます。
usersパラメーターにより、アンカーを共有するユーザーのOVRSpaceUserオブジェクトのコレクションを指定します。ShareAsync()の呼び出しが成功すると、指定されたユーザーはSSAを利用できるようになります。
public async void ShareExample(
OVRSpatialAnchor spatialAnchor,
IEnumerable<OVRSpaceUser> users)
{
var result = await spatialAnchor.ShareAsync(users);
if (result.IsSuccess())
{
BroadcastUuidToUsers(spatialAnchor.Uuid);
return;
}
switch (result)
{
case OVRSpatialAnchor.OperationResult.Failure_SpaceNetworkRequestFailed:
{
// Unable to reach Meta servers.
// Instruct user to check internet connection
break;
}
case OVRSpatialAnchor.OperationResult.Failure_SpaceCloudStorageDisabled:
{
// inform user to turn on Enhanced Spatial Services
// Settings > Privacy and Safety > Device Permissions > Turn on "Enhanced Spatial Services"
break;
}
// ...
}
}
アンカーを共有する一連のユーザーを指定する必要があります。そのためには、各ユーザーのMeta Quest ID (ulongの識別子)からOVRSpaceUserを作成します。
var users = new OVRSpaceUser[]
{
new OVRSpaceUser(userId1),
new OVRSpaceUser(userId2),
};
ShareExample(anchor, users);
現在のユーザーとその友達に関する情報を取得する方法については、
ユーザー、友達、関係 のセクションをご覧ください。
このスニペットは、ユーザーのコレクションに対して空間アンカーを共有する処理を示しています。
async void ShareExample(OVRSpatialAnchor anchor, OVRSpaceUser[] users)
{
var shareResult = await anchor.ShareAsync(users);
if (shareResult.IsError())
{
Debug.LogError($"Sharing failed with {shareResult}");
return;
}
Debug.Log($"Anchor {anchor.Uuid} shared with {users.Length} users.");
}
コロケーション共有空間アンカーエクスペリエンスでは、ユーザーの安全に特に注意する必要があります。複数のユーザーがMeta QuestヘッドセットやMeta VR Glassesを装着して物理スペースを共有している場合、特にデバイスの視野外では、お互いの位置や動きを完全には把握できないことがあります。
方向性のあるパススルー では、ヘッドセットの視野外にいるコロケーション環境のユーザーの方向にパススルーウィンドウがレンダリングされます。これにより、ユーザーは直接見えない近くにいる人の存在と方向を知ることができます。没入型VRエクスペリエンスでは、これはパススルーカットアウトとして表示されます。パススルーベースのエクスペリエンスでは、これを調整して、方向を示す合図として色付きのバーチャルコンテンツ(赤い帯など)を表示できます。セグメント型パススルー では、コロケーション環境の各ユーザーのトラッキング対象アバターの周囲にパススルーカットアウトが適用されます。カットアウトは姿勢推定エラーを考慮してアバターよりも広く設定され、下半身も含まれるように拡張されます。このサンプルでは、オールウェイズオンのパススルー、距離トリガーのパススルー、モメンタムトリガーのパススルーという複数のトリガーモードがサポートされています。これらのテクニックを組み合わせることで、トラッキング対象アバターの視覚上および聴覚上の位置が物理的なユーザーと完全には一致しない場合でも、他のユーザーに対する空間認識を維持しやすくなります。複合現実の安全に関する一般的なガイダンスについては、
複合現実のデザインガイドライン をご覧ください。
共有空間アンカーが正しい位置にローカライズされない場合があるという既知の問題があります。以下では、その問題点と対処法について説明します。
問題1:
再現手順
ホスト: ShareAsyncを呼び出す ホスト: アプリを終了する ホスト: デバイスを大幅に動かさない ホスト: アプリを再開する ホスト: ShareAsyncを呼び出す ゲスト: LoadUnboundSharedAnchorsAsyncを呼び出す ゲスト: 共有空間アンカーが正しい位置に読み込まれないことがある 対処法
ホストがアプリを終了した場合、ホストはデバイスを移動する必要があります 問題 2:
ゲストがローカルに保存しているアンカーが多すぎる可能性があります
対処法
[Settings (設定)] > [Privacy (プライバシー)] > [Clear Physical Space History (物理スペース履歴をクリア)]に移動します 空間アンカーについて、詳しくは以下のページをご覧ください。
Meta Questで空間アンカーを利用する方法を示すその他のサンプルについては、oculus-samplesのGitHubリポジトリをご覧ください。