Mixed Reality Utility Kit – Manage and query scene data
Updated: Jan 27, 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 dev 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 & 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 beahviour.
Never delete or modify MRUK room, anchor or trackables. Instead use the functionality on EffectMesh and AnchorPrefabSpawner to only visualize a specific room.
High-Fidelity Scene
MRUK supports the High-Fidelity Scene API.
HiFi scene provides a more detailed version of the room layout that allows features such as multiple floors, columns, and slanted ceilings to be queried by the developer.
To use HiFi Scene in MRUK, use the checkbox in MRUK Enable High Fidelity Scene.
New Features
Inner Wall Faces - A room can now have inner wall faces to represent complex architectural features such as columns, pillars, or other structural elements. These are represented by INNER_WALL_FACE, the new semantic label.
Multiple Floors - A room can now have multiple floors if detected by the space setup. This feature allows for more accurate representation of multi-story buildings or rooms with varying floor levels. The Scene API will provide separate floor planes for each distinct floor level, enabling developers to create more immersive and realistic experiences.
Multiple Ceilings - A room can now have multiple ceilings if detected by the space setup. This feature supports complex ceiling geometries, such as slanted or dropped ceilings, and allows developers to create more detailed and realistic environments. The Scene API will provide separate ceiling planes for each distinct ceiling, enabling developers to create more immersive and interactive experiences.
Visualizing the Scene with the Effect Mesh 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 (e.g., 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 (e.g., "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.