MRUK Space Sharing API – Share your room mesh with friends on Meta Quest

  • 11 June 2025
  • 11 June 2025
  • 4 min read
MRUK Space Sharing API – Share your room scan with friends with Meta Quest (Meta XR SDK v77)

Hi XR Developer! In this post, we’ll dive into Meta’s Space Sharing API (introduced in v74, refined in v77 of the XR SDK). With just a handful of lines of code and the help of MRUK, you can capture your room scan and share it in real time with nearby Quest devices via Bluetooth colocation. Everyone then sees the same mixed-reality content perfectly aligned to the host’s space. Let’s walk through the setup, the core workflow, and highlight the most important code parts.


🚀 Prerequisites & Setup

  1. Hardware & OS
    • Meta Quest 3/3S on Horizon OS v77 or later.
  2. SDKs & Packages
  3. Unity Scene
    • OVR Camera Rig + Passthrough Layer
    • MRUK + EffectMesh for room visualization
    • Nametag building block
  4. OVR Manager Permissions
    In your OVR Manager component, set both:
    • Colocation Session SupportRequired
    • Shared Spatial Anchor SupportRequired
  5. Device Settings
    • Quest connected to Wi-Fi
    • Settings → Privacy & Safety → Device Permissions → Enhanced Spatial ServicesOn
  6. Android Manifest
    • Meta → Tools → Create store-compatible AndroidManifest.xml OR Update AndroidManifest.xml (adds all necessary permissions)

🔄 Core Workflow

  1. Host
    • Advertises a Bluetooth colocation session → gets a group UUID
    • Shares its MRUK room UUID + floor-anchor pose via Photon Fusion
  2. Guest
    • Discovers the host’s group UUID via Bluetooth
    • Fetches the room UUID & pose from networked vars
    • Loads and aligns the shared room with MRUK

No manual scanning or QR codes—once the host advertises, all guests automatically download and align the same space.


⚙️ Code Highlights

1. Determine Role on Spawn

    private void PrepareColocation()
    {
        if (Object.HasStateAuthority)
        {
            AdvertiseColocationSession(); // Host
        }
        else
        {
            DiscoverNearbySession(); // Guests
        }
    }

2. Host: Advertise & Share MRUK Room

    private async void AdvertiseColocationSession()
    {
        var result = await OVRColocationSession.StartAdvertisementAsync(null);

        if (!result.Success)
        {
            Debug.LogError($"SpaceSharing: [Host] Advertisement failed: {result.Status}");
            return;
        }

        _sharedAnchorGroupId = result.Value;
        ShareMrukRooms();
    }

    private async void ShareMrukRooms()
    {
        var room = MRUK.Instance.GetCurrentRoom();
        NetworkedRoomUuid = room.Anchor.Uuid.ToString();
        var result = await room.ShareRoomAsync(_sharedAnchorGroupId);

        if (!result.Success)
        {
            Debug.LogError($"SpaceSharing: [Host] Failed to share MRUK rooms: {result.Status}");
            return;
        }

        var pose = room.FloorAnchor.transform;
        NetworkedRemoteFloorPose =
            $"{pose.position.x},{pose.position.y},{pose.position.z},{pose.rotation.x}," +
            $"{pose.rotation.y},{pose.rotation.z},{pose.rotation.w}";
    }

3. Guest: Discover & Join

    private async void DiscoverNearbySession()
    {
        OVRColocationSession.ColocationSessionDiscovered += OnColocationSessionDiscovered;
        var result = await OVRColocationSession.StartDiscoveryAsync();
    }

    private void OnColocationSessionDiscovered(OVRColocationSession.Data session)
    {
        OVRColocationSession.ColocationSessionDiscovered -= OnColocationSessionDiscovered;
        _sharedAnchorGroupId = session.AdvertisementUuid;
        LoadSharedRoom(_sharedAnchorGroupId);
    }

4. Load & Align the Shared Room

    private async void LoadSharedRoom(Guid groupUuid)
    {
        print($"SpaceSharing: [Client] Loading shared MRUK room: {groupUuid}");

        var roomUuid = Guid.Parse(NetworkedRoomUuid.ToString());
        var remotePoseStr = NetworkedRemoteFloorPose.ToString();
        var floorPose = ParsePose(remotePoseStr);

        var result = await MRUK.Instance.LoadSceneFromSharedRooms(null, groupUuid, (roomUuid, floorPose));
    
}

🧪 Testing Your Colocated Experience

  1. Build & upload a signed (add keystore) APK to a release channel on your Developer Dashboard.
  2. Invite testers or create test users—ensure they’re entitled.
  3. Install on two Quest devices, each under a different account.
  4. Run on Host:
    • Look for logs:
      • Advertisement started & group UUID
      • MRUK room shared & pose synced
  5. Run on Guest:
    • Logs confirming discovery, room load, and alignment
  6. Verify: Both headsets see the same MRUK mesh and Nametag positions.

🎯 Conclusion

Meta’s Space Sharing API makes colocated MR experiences a breeze—no QR codes, no manual alignment. With MRUK handling the room scan, OVRColocationSession for discovery, and just a few networked vars, everyone in your session shares the same context instantly. Grab the full source on my Patreon, hit Like & Subscribe, and join our Discord for questions. Happy sharing!


Support XR DEV ROB🐋

Thank you for following this article. Stay tuned for more in-depth and insightful content in the realm of XR development! 🌐

Did this article help you out? Consider supporting me on Patreon, where you can find all the source code, or simply subscribe to my YouTube channel!

Leave a Reply

Your email address will not be published. Required fields are marked *