Mixed Reality Utility Kit – Manage and query scene data
Updated: Jul 6, 2026
Learning objectives
Configure the MRUK prefab to bootstrap scene data and define application behavior.
Stabilize your virtual scene using World Locking to minimize drift and simplify anchor workflows.
Select and combine data sources (Device, Prefab, JSON) with fallback strategies for development and production.
Control script execution order on scene-loaded events to manage complex initialization.
Leverage MRUK, MRUKRoom, MRUKAnchor, and MRUKTrackables APIs for spatial queries.
Scene capture and startup
To enable MRUK’s spatial queries, you must first generate a Scene Model using the Space Setup flow. This process captures planes, volumes, and mesh geometry of the physical environment.
Follow the on‑device Space Setup by navigating to Settings → Environment Setup → Space Setup. The guided scan walks users around their environment to capture necessary data, with a manual capture fallback if automatic detection struggles. You can also enable Load Scene on Startup in the MRUK prefab to auto‑trigger this flow, or call OVRScene.RequestSpaceSetup() programmatically.
On-device Flow:
Navigate to Settings → Physical Space → Space Setup on the headset.
Follow the guided scan; if automatic detection struggles, switch to manual capture to outline key surfaces.
Auto-trigger:
In the MRUK prefab inspector, enable Load Scene on Startup. If no scene exists, MRUK will prompt Space Setup at app launch.
Programmatic Invocation:
OVRScene.RequestSpaceSetup();
Link Limitation
Space Setup must run on‑device. You cannot perform Space Setup via Meta Horizon Link.
MRUK class
Place the MRUK.prefab (Core/Prefabs/MRUK.prefab) into your scene and configure its sections:
World Locking
World Locking keeps virtual content stationary relative to the real world without manually parenting every object to anchors. With EnableWorldLock (default true), MRUK applies subtle tracking‑space adjustments so anchors remain aligned. This allows your virtual objects to stay “static” in world space, improving stability and reducing the need to parent to each anchor.
When implementing custom camera control and World Locking is enabled, use the TrackingSpaceOffset transform matrix field in MRUK to move the tracking space.
Data source selection
MRUK supports three scene data inputs. Choose one or combine them via inspector dropdown or API:
Device: Live scan via OpenXR or XR Simulator. Reflects the user’s actual room.
Prefab: ~50 built-in sample rooms (Core/Rooms/Prefabs) for quick editor testing without scanning.
JSON: Pre-captured Scene Models (Core/Rooms/Json) for sharing or multiplayer synchronization.
Many initialization scripts depend on scene data. Under Script Execution, list your MonoBehaviours to fire on SceneLoadedEvent in the correct sequence. Here is the ordering of the FloorZone example:
BasicWallDecorator: Apply color schemes or tags to primary walls.
VolumeDecorator: Highlight furniture volumes or other semantic zones.
FindSpawnPositions: Compute valid floor or surface points for gameplay elements.
This ordering guarantees that decorations are applied before spawn calculations run.
Working with scene data
After loading, MRUK exposes comprehensive APIs for querying rooms, anchors, and trackables.
MRUK: Singleton manager. Loads, clears, and raises global events.
MRUKRoom: Represents one scanned room—contains anchors and spatial utilities.
MRUKAnchor: Planes (walls, floor, ceiling), volumes (furniture), and mesh geometry with semantic labels.
MRUKTrackable: Dynamic anchors (e.g., keyboards) with detection events.
The rooms, anchors, and trackables that have been loaded by MRUK should never be deleted or modified from the outside. Doing so will lead to undefined behavior. See Effect Mesh and AnchorPrefabSpawner for more information on how to only visualize a specific room.
Events & Callbacks
Subscribe to:
MRUK.Instance.SceneLoadedEvent when all rooms finish loading.
RoomCreatedEvent / RoomUpdatedEvent as rooms change.
Always check MRUK.IsSupported before using MRUK APIs.
Cache room and anchor references when accessed frequently to reduce overhead.
Unsubscribe from events in OnDestroy() to prevent unexpected behaviour.
Never delete or modify MRUK room, anchor, or trackables. Instead use the functionality on EffectMesh and AnchorPrefabSpawner to only visualize a specific room.
Visualizing the scene with the EffectMesh class
EffectMesh creates special‑effect meshes from your Scene anchors—planes become triangulated meshes, volumes become cuboids, and the global scene mesh uses its raw geometry. You can apply custom UV mappings, vertex coloring, and optional colliders or hole‑cuts for doors and windows.
How to use
Drag the EffectMesh prefab (Core/Prefabs/EffectMesh.prefab) into your scene.
Assign a Mesh Material to define colors, outlines, or custom shaders.
Enable Add Colliders to allow physics interactions (for example, bouncing or placement checks).
Toggle Hide Mesh if you only need colliders or shader-driven effects without visible geometry.
Check Cut Holes to automatically remove quads where door and window frames appear.
EffectMesh settings
Spawn On Start: Controls whether an effect mesh is automatically applied to all rooms, a specific room, or no rooms, allowing for manual application if desired.
Mesh Material: Material applied to all generated primitives. Use multiple EffectMesh instances for layered materials.
Border Size: Thickness of edge bounds. Edge vertices are black, fading to white over this distance—ideal for outline shaders.
Frames Offset: Extrudes co-planar quads (doors/windows) off the wall by this many meters to prevent Z-fighting.
Add Colliders: When true, colliders are added to each mesh primitive.
Cast Shadows: Controls whether effect meshes cast shadows in the scene.
Hide Mesh: Hides the visual mesh but retains colliders and shader interactions.
Texture Coordinate Mode:
METRIC: UVs increase 1 unit per meter.
METRIC_SEAMLESS: 1 unit per meter, adjusted to end on integers to avoid seams.
MAINTAIN_ASPECT_RATIO: UVs scaled to preserve texture aspect ratio.
MAINTAIN_ASPECT_RATIO_SEAMLESS: Aspect-ratio UVs ending on whole numbers.
STRETCH: UVs mapped from 0 to 1 across each primitive.
Labels: List of semantic labels (for example, "Wall", "Floor", "GlobalMesh") to include in the generated meshes.
Related samples
MRUKBase
A minimal scene with MRUK, EffectMesh (using the neon-blue RoomBoxEffects material with 1 m floor/ceiling crosses and stretched UVs), and SceneDebugger to visualize spatial queries.
This sample uses EffectMesh colliders (hidden mesh) to let virtual balls bounce off the physical environment. BouncingBallMgr spawns balls on Grab and shoots them on Trigger; BouncingBallLogic plays collision audio and self-destructs after a delay.