Space Sharing Unity
Updated: Mar 13, 2025
The new Unity Space Sharing APIs built into the
Mixed Reality Utility Kit (MRUK) allow developers to build colocated apps where all participants can leverage detailed information about their physical surroundings (for example, location and dimensions of walls, floor, doors, and furniture). Developers should consider using Space Sharing when their apps can benefit from the contextual information surfaced by
Scene. See
Space Sharing Overview for more high-level information on this feature.
Shared Spatial Anchors (SSA) may be the correct choice for developers looking to build colocated apps that do not require Scene information. For example, apps that have a single, small (1-3 square meter) piece of content that does not need to adapt to the users’ environment.
Space Sharing is accomplished when a single participant (the host) shares their local Scene data with one or more participants that will load it (guests). The sharing and loading of Scene data is handled via MRUK, but the application code does need to create an arbitrary UUID to share and load the scene. The arbitrary UUID can be thought of as the rendezvous point (i.e. a place where the Host can share the scene and the Guest knows to load the scene from the arbitrary UUID).
The sequence diagram below illustrates a typical flow for the application instance acting as a Host sharing locally loaded Scene data with one or more Guests. It includes interactions between MRUK, Core SDK, application code, and a generic networking library.
The sequence diagram below illustrates a typical flow for the application instance acting as a guest for loading shared Scene data from the Host. It includes interactions between MRUK.
Coordinate frame alignment Once the Host and Guest have successfully shared the scene anchors for their colocated space, the application code can use the floor anchor of any shared room as a basis for a shared coordinate frame. MRUK provides helpers to achieve this alignment, but requires some code in the application to make it work. The Host should pick a room for alignment (typically this should be
MRUK.Instance.GetCurrentRoom()
). The pose of the floor anchor (
position
/
rotation
from
room.FloorAnchor.transform
) should be serialized along with the room UUID and sent to the Guest using a networking library or as
colocationSessionData
when using
Colocation Discovery. The Guest should pass the data received from the Host to the
LoadSceneFromSharedRooms
function call using the
alignmentData
parameter. MRUK will then make sure the room is loaded on the Guest in the same Unity global coordinate frame as on the Host. MRUK
EnableWorldLock
should be set to true in order for it to adjust the camera position so that the room aligns with the physical room. At this point, alignment between the Guest and Host is complete and any game objects with the same world position will appear in the same physical location on both devices.
Space Sharing API uses functions that belong in MRUK, for details refer to the other
MRUK functionsShareRoomsAsync()
is called by the host to share the MRUK room
/// <summary>
/// Shares multiple MRUK rooms with a group
/// </summary>
/// <param name="rooms">A collection of rooms to be shared.</param>
/// <param name="groupUuid">UUID of the group to which the room should be shared.</param>
/// <returns>A task that tracks the asynchronous operation.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="rooms"/> is `null`.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="groupUuid"/> equals `Guid.Empty`.</exception>
public OVRTask<OVRResult<OVRAnchor.ShareResult>> ShareRoomsAsync(IEnumerable<MRUKRoom> rooms,
Guid groupUuid)
LoadSceneFromDevice()
is used by the Host to load local Scene data.
LoadSceneFromSharedRooms()
is used by the Guest to load shared Scene data.
/// <summary>
/// Loads the scene based on scene data previously shared with the user via
/// <see cref="MRUKRoom.ShareRoomAsync"/>.
/// </summary>
/// <remarks>
///
/// This function should be used in co-located multi-player experiences by "guest"
/// clients that require scene data previously shared by the "host".
///
/// </remarks>
/// <param name="roomUuids">A collection of UUIDs of room anchors for which scene data will be loaded from the given group context.</param>
/// <param name="groupUuid">UUID of the group from which to load the shared rooms.</param>
/// <param name="alignmentData">Use this parameter to correctly align local and host coordinates when using co-location.<br/>
/// alignmentRoomUuid: the UUID of the room used for alignment.<br/>
/// floorWorldPoseOnHost: world-space pose of the FloorAnchor on the host device.<br/>
/// Using 'null' will disable the alignment, causing the mismatch between the host and the guest. Do this only if your app has custom coordinate alignment.</param>
/// <param name="removeMissingRooms">
/// When enabled, rooms that are already loaded but are not found in roomUuids will be removed.
/// This is to support the case where a user deletes a room from their device and the change needs to be reflected in the app.
/// </param>
/// <returns>An enum indicating whether loading was successful or not.</returns>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="roomUuids"/> is `null`.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="groupUuid"/> equals `Guid.Empty`.</exception>
/// <exception cref="ArgumentException">Thrown if <paramref name="alignmentData.alignmentRoomUuid"/> equals `Guid.Empty`.</exception>
public async Task<LoadDeviceResult> LoadSceneFromSharedRooms(IEnumerable<Guid> roomUuids, Guid groupUuid, (Guid alignmentRoomUuid, Pose floorWorldPoseOnHost)? alignmentData, bool removeMissingRooms = true)
The automatic prompting for the
Enhanced Spatial Services permission does not work reliably in some versions of the OS. Please ensure all users enable
this permission manually ahead of running the sample.
Unity Open XR Plugin is currently not supported Space shared is sometimes not aligned There are known issues where a scene anchor may not be localized at the correct location. The below talks about the issues and how to mitigate them.
Issue 1:
- Repro Steps
- Host: Calls ShareRoomAsync
- Host: Quits App
- Host: Does not significantly move their Quest device
- Host: Reopens App
- Host: Calls ShareRoomAsync
- Guest: Calls LoadSceneFromSharedRooms
- Guest: May observe scene anchor not loaded at the correct location
- Mitigation
- If Host quits app, the Host should move their Quest device
Issue 2:
The Guest may have too many anchors stored locally
- Mitigation
- Go to Settings > Privacy > Clear Physical Space History