From meta-vr
Provides high-level tools for scene-aware mixed reality development in Unity using Meta XR MRUK, including scene loading, world locking, prefab spawning, and environment raycasting.
How this skill is triggered — by the user, by Claude, or both
Slash command
/meta-vr:hz-unity-meta-mixed-reality-utility-kitThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The Meta XR Mixed Reality Utility Kit (MR Utility Kit, MRUK) is a Unity package that provides high-level tools on top of the Scene API for building scene-aware Mixed Reality (MR) experiences. It is designed to be used in conjunction with the Meta XR Core SDK.
The Meta XR Mixed Reality Utility Kit (MR Utility Kit, MRUK) is a Unity package that provides high-level tools on top of the Scene API for building scene-aware Mixed Reality (MR) experiences. It is designed to be used in conjunction with the Meta XR Core SDK. It handles scene data loading and querying, spawning prefabs on real-world surfaces, world locking to prevent anchor drift, environment raycasting for instant placement without scanning, passthrough camera access, NavMesh generation from room geometry, and trackable detection (keyboards, QR codes).
Package: com.meta.xr.mrutilitykit
The package com.meta.xr.mrutilitykit may be located in different places depending on the project setup:
Library/PackageCache/com.meta.xr.mrutilitykit@<hash>/ (cached from registry)Packages/com.meta.xr.mrutilitykit/ (local package reference)Before searching for SDK source, first locate the package root by searching for a known file by filename pattern:
**/com.meta.xr.mrutilitykit*/Core/Scripts/MRUK.cs
Then use the resolved parent path for all subsequent search operations.
| Task | Class / Component | Source File | Key Entry Point |
|---|---|---|---|
| Load scene from device | MRUK | Scripts/MRUK.cs | LoadSceneFromDevice() |
| Load scene from prefab/JSON | MRUK | Scripts/MRUK.cs | LoadSceneFromPrefab(), LoadSceneFromJsonString() |
| Get current room | MRUK | Scripts/MRUK.cs | GetCurrentRoom() |
| Prevent anchor drift | MRUK | Scripts/MRUK.cs | EnableWorldLock = true |
| Query room geometry | MRUKRoom | Scripts/MRUKRoom.cs | Raycast(), IsPositionInRoom() |
| Find surfaces / closest point | MRUKRoom | Scripts/MRUKRoom.cs | TryGetClosestSurfacePosition(), GenerateRandomPositionOnSurface() |
| Get anchor properties | MRUKAnchor | Scripts/MRUKAnchor.cs | Label, PlaneRect, VolumeBounds |
| Spawn prefabs on anchors | AnchorPrefabSpawner | Scripts/AnchorPrefabSpawner.cs | PrefabsToSpawn, SpawnOnStart |
| Find random spawn positions | FindSpawnPositions | Scripts/FindSpawnPositions.cs | StartSpawn(), SpawnLocations |
| 27-slice mesh resizing | GridSliceResizer | Scripts/GridSliceResizer.cs | ResizeTo(Vector3) |
| Generate visual meshes | EffectMesh | Scripts/EffectMesh.cs | CreateMesh(), CutHoles |
| Breakable scene geometry | DestructibleGlobalMeshSpawner | Scripts/DestructibleGlobalMeshSpawner.cs | CreateOnRoomLoaded |
| GPU distance field texture | SpaceMapGPU | Scripts/SpaceMapGPU.cs | GetSpaceMap(), StartSpaceMap() |
| Boundary proximity fade | RoomGuardian | Scripts/RoomGuardian.cs | GuardianDistance, GuardianMaterial |
| NavMesh from scene | SceneNavigation | Scripts/SceneNavigation.cs | BuildSceneNavMesh() |
| Depth API raycasting | EnvironmentRaycastManager | Scripts/EnvironmentRaycastManager.cs | Raycast(), PlaceBox() |
| Passthrough camera images | PassthroughCameraAccess | Scripts/PassthroughCameraAccess.cs | GetTexture(), GetCameraPose() |
| Track keyboards / QR codes | MRUKTrackable | Scripts/MRUKTrackable.cs | TrackableType, MarkerPayloadString |
| Instant placement (no scan) | PointAndLocate | Scripts/BuildingBlocks/InstantContentPlacement/ | TryLocateSpace() |
| Share rooms (multiplayer) | MRUK | Scripts/MRUK.cs | ShareRoomsAsync(), LoadSceneFromSharedRooms() |
All source file paths are relative to the package root (see "Finding the SDK Source" above).
MRUK (singleton MonoBehaviour)
└── MRUKRoom (child GameObjects, one per room)
└── MRUKAnchor (children of rooms: walls, floors, furniture, etc.)
MRUK.Instance is the central hub. It loads scene data, manages rooms, handles world locking, and provides the SceneSettings configuration.MRUKRoom represents a physical room. Provides spatial queries (raycasting, position checks, surface queries) and holds Anchors, WallAnchors, FloorAnchors, CeilingAnchors, GlobalMeshAnchor.MRUKAnchor represents a single scene element (wall, table, couch, etc.). Has a Label (SceneLabels flags), optional PlaneRect (2D bounds), VolumeBounds (3D bounds), and PlaneBoundary2D (polygon points).MRUKTrackable extends MRUKAnchor for runtime-detected objects (keyboards, QR codes).A C/C++ shared library handles world locking, anchor discovery, and coordinate conversion (OpenXR right-handed ↔ Unity left-handed). A hidden MRUKGlobalContext MonoBehaviour (DontDestroyOnLoad) ticks the native context every frame. You never call these directly.
All feature components (AnchorPrefabSpawner, EffectMesh, FindSpawnPositions, SceneNavigation, SpaceMapGPU, RoomGuardian, DestructibleGlobalMeshSpawner) follow the same pattern:
SpawnOnStart / CreateOnStart / BuildOnSceneLoaded property of type MRUK.RoomFilter controls automatic initializationStart(), they call MRUK.Instance.RegisterSceneLoadedCallback(...) which fires immediately if the scene is already loadedCreateMesh(), StartSpawn(), BuildSceneNavMesh(), etc.) for programmatic controlcom.meta.xr.sdk.core (OVRCameraRig, OVRPlugin, OVRSpatialAnchor, OVRSemanticLabels)com.unity.ai.navigation (for SceneNavigation)com.unity.nuget.newtonsoft-json (for JSON scene serialization)FLOOR, CEILING, WALL_FACE, TABLE, COUCH, DOOR_FRAME, WINDOW_FRAME,
OTHER, STORAGE, BED, SCREEN, LAMP, PLANT, WALL_ART, GLOBAL_MESH,
INVISIBLE_WALL_FACE, UNKNOWN, INNER_WALL_FACE
Use as flags: SceneLabels.TABLE | SceneLabels.COUCH matches tables OR couches.
None = 0, Plane = 1, Volume = 2, All = Plane | Volume
Anchors can have plane geometry (2D rect), volume geometry (3D bounds), or both.
Device // Load from device Scene API
Prefab // Load from room prefab GameObjects
DeviceWithPrefabFallback // Device first, prefab if no scene data (recommended for dev)
Json // Load from JSON string
DeviceWithJsonFallback // Device first, JSON if no scene data
FACING_UP = 1 // Floors, table tops
FACING_DOWN = 2 // Ceilings, undersides
VERTICAL = 4 // Walls
None // Don't auto-initialize
CurrentRoomOnly // Only the room the user is in
AllRooms // All loaded rooms
V1 // Standard scene model
V2 // High Fidelity: multiple floors/ceilings, slanted ceilings, inner walls
V2FallbackV1 // Try V2, fall back to V1 if unsupported
Struct for filtering anchors by label and component type. Used in raycast, surface query, and spawn methods.
var filter = new LabelFilter(SceneLabels.TABLE | SceneLabels.COUCH, ComponentType.Volume);
bool passes = filter.PassesFilter(anchor.Label);
DEFAULT // Standard positioning
CENTER // Center of surface (e.g., center of table for chess board)
EDGE // Edge of surface (e.g., edge of table for piano)
Key Properties: Instance (static), IsInitialized, Rooms (List<MRUKRoom>), EnableWorldLock, IsWorldLockActive, TrackingSpaceOffset, SceneSettings
Key Methods:
GetCurrentRoom() → MRUKRoomRegisterSceneLoadedCallback(UnityAction) — fires immediately if already loadedLoadSceneFromDevice(SceneModel) → Task<LoadDeviceResult>LoadSceneFromPrefab(GameObject) → Task<LoadDeviceResult>LoadSceneFromJsonString(string) → Task<LoadDeviceResult>SaveSceneToJsonString() → stringClearScene()HasSceneModel() → Task<bool> (static, checks if device has scene data)ShareRoomsAsync(...), LoadSceneFromSharedRooms(...) — co-located multiplayerEvents: SceneLoadedEvent, RoomCreatedEvent, RoomUpdatedEvent, RoomRemovedEvent
MRUKSettings (serialized config): DataSource, RoomPrefabs[], SceneJsons[], LoadSceneOnStartup, EnableHighFidelityScene, SeatWidth, TrackerConfiguration
Key Properties: Anchors, WallAnchors, FloorAnchors, CeilingAnchors, GlobalMeshAnchor, IsLocal, RoomMeshData
Key Methods:
Raycast(Ray, float, out RaycastHit, out MRUKAnchor) — collisionless raycast against scene geometryRaycastAll(...) — all intersectionsIsPositionInRoom(Vector3), IsPositionInSceneVolume(Vector3)TryGetClosestSurfacePosition(Vector3, out Vector3, out MRUKAnchor, LabelFilter) → float (distance)GenerateRandomPositionOnSurface(SurfaceType, float, LabelFilter, out Vector3, out Vector3) → boolGenerateRandomPositionInRoom(float, bool) → Vector3?FindLargestSurface(SceneLabels) → MRUKAnchorGetRoomBounds() → BoundsGetKeyWall(out Vector2, float) → MRUKAnchor (widest wall facing room center)Events: AnchorCreatedEvent, AnchorUpdatedEvent, AnchorRemovedEvent
Key Properties: Label (SceneLabels), PlaneRect (Rect?), VolumeBounds (Bounds?), PlaneBoundary2D (List<Vector2>), Room (MRUKRoom), ParentAnchor, ChildAnchors, GlobalMesh (Mesh)
Key Methods:
Raycast(Ray, float, out RaycastHit, ComponentType) — collisionless raycastHasAnyLabel(SceneLabels) → boolGetAnchorCenter() → Vector3GetClosestSurfacePosition(Vector3, out Vector3, out Vector3, ComponentType) → floatIsPositionInVolume(Vector3), IsPositionInBoundary(Vector2)Runtime-tracked objects (keyboards, QR codes). Managed by MRUK via SceneSettings.TrackerConfiguration.
Key Properties: TrackableType (OVRAnchor.TrackableType), IsTracked, MarkerPayloadString, MarkerPayloadBytes
Events on SceneSettings: TrackableAdded, TrackableRemoved
Scripts/AnchorPrefabSpawner.cs)Spawns prefabs on scene anchors based on labels. Configure PrefabsToSpawn (List<AnchorPrefabGroup>) mapping labels to prefab lists with scaling/alignment modes.
AnchorPrefabGroup: Labels, Prefabs, PrefabSelection (Random/ClosestSize/Custom), Scaling (Stretch/UniformScaling/UniformXZScale/NoScaling/Custom), Alignment (Automatic/Bottom/Center/NoAlignment/Custom), MatchAspectRatio, CalculateFacingDirection
Methods: SpawnPrefabs(), SpawnPrefabs(MRUKRoom), ClearPrefabs()
Scripts/FindSpawnPositions.cs)Generates random valid positions for spawning objects. Supports floating, surface-mounted, and hanging positions with physics overlap checking.
SpawnLocation enum: Floating, AnySurface, VerticalSurfaces, OnTopOfSurfaces, HangingDown
Key props: SpawnObject, SpawnAmount, MaxIterations, Labels, CheckOverlaps, SurfaceClearanceDistance
Scripts/GridSliceResizer.cs)27-slice 3D mesh resizer (3D analogue of 9-slice). Preserves mesh borders/corners while stretching the interior to match anchor dimensions. Attach to prefabs used with AnchorPrefabSpawner.
Scripts/EffectMesh.cs)Generates visual meshes from scene anchors. Supports materials, colliders, hole cutting (for doors/windows), shadow casting, and visibility toggling.
Key props: MeshMaterial, Colliders, CutHoles (SceneLabels to cut holes for), CastShadow, HideMesh
Methods: CreateMesh(), DestroyMesh(), ToggleEffectMeshVisibility(bool), ToggleEffectMeshColliders(bool)
Casts virtual lights' shadows and highlights onto real-world surfaces by rendering an EffectMesh with the Meta/MRUK/Scene/HighlightsAndShadows shader (TransparentSceneAnchor.mat). Silent-failure heavy — the most common gotcha is the URP Renderer asset's Transparent Receive Shadows flag must be ON, otherwise shadows never appear on the floor.
For setup, URP/EffectMesh/passthrough requirements, common failure modes, and editor verification, see references/passthrough-relighting.md.
Scripts/DestructibleGlobalMeshSpawner.cs)Segments the global mesh into breakable fragments using Voronoi-based segmentation.
Key props: GlobalMeshMaterial, PointsPerUnitX/Y/Z (density), ReservedTop/Bottom (unbreakable zones)
Scripts/SpaceMapGPU.cs)GPU-computed 2D top-down distance field of the room layout. Outputs to RenderTexture.
Key props: TextureDimension, MapGradient; Methods: GetSpaceMap() → RenderTexture, GetColorAtPosition(Vector3) → Color
Sets shader global _SpaceMapProjectionViewMatrix for UV calculation.
Scripts/RoomGuardian.cs)Fades a boundary material as the user approaches room walls. Sets _GuardianFade float on the material.
Key props: GuardianMaterial, GuardianDistance (meters, default 1.0)
Scripts/SceneNavigation.cs)Generates Unity NavMesh from scene geometry. Requires com.unity.ai.navigation.
Key props: NavigableSurfaces (SceneLabels), Agents (List<NavMeshAgent>), AgentRadius
Events: OnNavMeshInitialized
For more info see references/scene-navigation.md.
Scripts/EnvironmentRaycastManager.cs)Depth API raycasting against the physical environment without requiring pre-scanned scene data. Requires Quest 3+. Namespace: Meta.XR.
Check EnvironmentRaycastManager.IsSupported before use.
Methods: Raycast(Ray, out EnvironmentRaycastHit, float), PlaceBox(Ray, Vector3, Vector3, out EnvironmentRaycastHit), CheckBox(Vector3, Vector3, Quaternion)
Scripts/PassthroughCameraAccess.cs)Raw passthrough camera image access. Requires horizonos.permission.HEADSET_CAMERA in AndroidManifest. Quest 3+ only. Namespace: Meta.XR.
Key props: CameraPosition (Left/Right), RequestedResolution, MaxFramerate, TargetMaterial
Methods: GetTexture() → Texture, GetColors() → NativeArray<Color32> (expensive), GetCameraPose() → Pose, ViewportPointToRay(), WorldToViewportPoint()
Struct CameraIntrinsics: FocalLength, PrincipalPoint, SensorResolution, LensOffset
Scripts/BuildingBlocks/InstantContentPlacement/)Building block scripts using EnvironmentRaycastManager for device-scan-free placement:
SpaceLocator (abstract): TryLocateSpace(out Pose), OnSpaceLocateCompleted event, PreferredSurfaceOrientationPointAndLocate: raycast from a Transform, Locate() methodGrabAndLocate: grab-and-release placement via Interaction SDKPlaceWithAnchor: creates OVRSpatialAnchor at placed position to prevent driftvoid Start()
{
MRUK.Instance.RegisterSceneLoadedCallback(OnSceneLoaded);
}
void OnSceneLoaded()
{
var room = MRUK.Instance.GetCurrentRoom();
// Scene is ready — query anchors, spawn objects, etc.
}
RegisterSceneLoadedCallback fires immediately if the scene is already loaded — safe to call at any time.
var room = MRUK.Instance.GetCurrentRoom();
foreach (var anchor in room.Anchors)
{
if (anchor.HasAnyLabel(MRUKAnchor.SceneLabels.TABLE | MRUKAnchor.SceneLabels.STORAGE))
{
Debug.Log($"{anchor.Label} at {anchor.GetAnchorCenter()}");
}
}
var room = MRUK.Instance.GetCurrentRoom();
var ray = new Ray(origin, direction);
if (room.Raycast(ray, Mathf.Infinity, out var hit, out var anchor))
{
Debug.Log($"Hit {anchor.Label} at {hit.point}, normal {hit.normal}");
}
Set MRUK.SceneSettings.DataSource to DeviceWithPrefabFallback and assign room prefabs in SceneSettings.RoomPrefabs. On device, real scene data is used. In editor (no device), prefab rooms load automatically. The package includes ~50 sample room prefabs under Core/Rooms/Prefabs/ (Bedroom, LivingRoom, Office, LargeScale).
com.meta.xr.mrutilitykit packageOVRCameraRig is in the sceneMRUK GameObject with the MRUK component to the sceneSceneSettings.DataSource (use DeviceWithPrefabFallback for development)horizonos.permission.HEADSET_CAMERA to AndroidManifest and regenerate via OVRManifestPreprocessor.GenerateOrUpdateAndroidManifest()MRUK classes live in the Meta.XR.MRUtilityKit namespace in the meta.xr.mrutilitykit assembly, which is not directly referenceable from Unity MCP compiled scripts. Use runtime reflection:
// 1. Find the type
System.Type t = null;
foreach (var asm in System.AppDomain.CurrentDomain.GetAssemblies())
{
try { t = asm.GetType("Meta.XR.MRUtilityKit.MRUK"); } catch { }
if (t != null) break;
}
// 2. Get method (no BindingFlags — parameterless overload only)
var m = t.GetMethod("GetCurrentRoom");
// 3. Get singleton instance
var instanceProp = t.GetProperty("Instance");
var instance = instanceProp.GetValue(null);
// 4. Invoke
var room = m.Invoke(instance, null);
Rules: Never add using System.Reflection; (causes MCP crashes). Never use BindingFlags overloads. Always catch System.Reflection.TargetInvocationException and log InnerException.
If the metavr MCP server is available, use the mcp__metavr__meta_docs_search and mcp__metavr__meta_docs_get_page tools to verify current API details, as Meta SDK documentation updates frequently. Use mcp__metavr__search_api_reference with engine='unity' to look up exact method signatures for MRUK, MRUKRoom, MRUKAnchor, and other classes.
npx claudepluginhub meta-quest/agentic-tools --plugin meta-vrConfigures Meta XR Core SDK for Unity VR/MR projects on Quest headsets. Covers OVRCameraRig, OVRManager, passthrough, hand tracking, spatial anchors, and Android manifest generation.
Unity 6 XR development guide. Use when building VR, AR, or MR experiences. Covers XR Interaction Toolkit, XR Plug-in Management, OpenXR, hand tracking, controllers, haptics, AR Foundation (plane detection, anchors, image tracking), and platform-specific setup (Meta Quest, Apple Vision Pro). Based on Unity 6.3 LTS documentation.
Sets up OpenXR for VR/AR/XR apps in Godot 4.3+ with XROrigin3D, controllers, hand tracking, passthrough, and Meta Quest deployment.