Mixed Reality Utility Kit - Working with Scene Data
Updated: Mar 13, 2025
After completing this section, the developer should understand the use of the MRUK, MRUKRoom, and MRUK Anchor Prefabs in a typical application flow.
MRUK is a singleton class, and there should only be one instance of this in your scene. It is responsible for loading the scene data either from device, prefabs or JSON. MRUK provides an abstraction over the scene data returned during scene setup or associated with anchors created by the application. It is useful to understand the scene graph and different types of anchors described in the
Scene Overview.
When loading from a device, MRUK will use the OpenXR APIs to access the scene data. This is also compatible with
XR Simulator, if you have a room loaded in XR Sim with scene data it will be able to load data from XR Sim instead. Please note that XR Sim may show benign warnings, such as logging “not supported” when querying the space component status.
For fast iteration in the Unity editor, you can also load data from Prefabs. There is a selection of about 50 scenes to choose from, containing bedrooms, living rooms, offices, and other spaces, which can be found in Core/Rooms/Prefabs. These can be copied and modified in the Unity editor to create your own custom rooms for testing purposes. Note that prefab rooms don’t include Scene Mesh.
Additionally, you can save and load scenes to and from JSON. This can be useful to capture your own scene and load it into the editor or to send over the network for multiplayer experiences. You will also find a selection of pre-captured JSON scenes under Core/Rooms/Json.
Once the Scene Data is loaded, the MRUK class is where you can access the data through the Rooms property and the GetCurrentRoom() function. There are also events that can be listened to for when new scene data is loaded. The SceneLoadedEvent triggers once all rooms are loaded, RoomCreatedEvent, RoomUpdatedEvent & RoomRemovedEvent events are triggered when rooms are created, updated or removed, respectively.
The
MRUKRoom class represents a room that has been captured through Space Setup. This contains a list of MRUKAnchors within the room, along with a set of utility functions to perform queries on the scene. A few examples are Raycast/RaycastAll, GetKeyWall, IsPositionInRoom, IsPositionInSceneVolume, TryGetClosestSurfacePosition, etc. Similarly to the MRUK class, there are AnchorCreatedEvent, AnchorUpdatedEvent & AnchorRemovedEvent events which are triggered once anchors within the room are created, updated or removed, respectively.
The
MRUKAnchor class represents a
Scene Anchor in the Scene Model. It has a transform, semantic label and optionally a plane and/or volume associated with it. The
Scene Mesh is also represented by an anchor and has a triangular mesh associated with it. There are a number of utility functions associated with the class for ray casting, finding closest surface position, checking if a point is in the boundary, etc.
The
MRUKTrackable class is a type of MRUKAnchor that can be detected and tracked, like physical keyboards. It derives from the MRUKAnchor and has optional properties like a plane and volume associated with it. Because trackables can change over time, their transforms and other properties are updated at regular intervals.
The MRUK component allows you to configure the types of trackables to track and provides events to let you know when a trackable has been detected (TrackableAdded) or is no longer detected (TrackableRemoved). On the MRUK component, expand Scene Settings > Tracker Configuration to configure the trackers.
How to Use:
Typical apps will have logic for manipulating scene data that:
- Calls
MRUK.Instance.GetCurrentRoom()
to pick up the scene graph for the current room.
var myRoom = MRUK.Instance.GetCurrentRoom();
- Iterate through the MRUKRoom properties to navigate the scene graph or find objects of interest. In this step, MRUKAnchor.label representing the objects in the scene can be used to filter for the identified objects. Objects can also be identified with one of the other MRUKRoom like GetKeyWall(),TryGetClosestSurfacePosition() or FindLargestSurface().
// Get the key wall. This is the longest wall with no other room points behind it. This is a good wall
// to be used as a 'stage' or to place a big screen on, for example.
var keyWallAnchor = myRoom.GetKeyWall(out Vector2 wallScale);
// Spawn a quad and place it on the keyWallAnchor wall.
var spawnedQuad = GameObject.CreatePrimitive(PrimitiveType.Quad);
spawnedQuad.transform.position = keyWallAnchor.gameObject.transform.position;
spawnedQuad.transform.localScale = wallScale;
spawnedQuad.transform.localRotation = keyWallAnchor.transform.rotation;
- The objects discovered can be 2D plane objects like ceilings or floor or 3D objects containing a volume. The surface area can be calculated from the anchor using the anchor.VolumeBounds to determine if there is enough room for the planned game activity or virtual object.