The AnchorPrefabSpawner prefab inspects each MRUK anchor’s semantic label and bounds, then selects, aligns, and scales a prefab to fit. Use it to automatically decorate walls, furniture volumes, or floors without manual positioning.
Configuration
SpawnOnStart: Controls whether the AnchorPrefabSpawner is automatically applied to all rooms, a specific room, or no rooms, allowing for manual application if desired.
PrefabsToSpawn: One or more AnchorPrefabGroup entries—each groups a semantic label with a prefab list.
SelectionMode:
Random for nondeterministic choice (use SeedValue for repeatability).
ClosestSize picks the prefab whose size best matches the anchor.
Custom to override via CustomPrefabSelection().
ScalingMode:
Stretch to exactly match anchor extents.
UniformScaling preserves aspect ratio on all axes.
UniformXZScale scales horizontally but not vertically.
NoAlignment or Custom via CustomPrefabAlignment().
SeedValue: Random seed for deterministic selection.
Sample Usage
After the scene loads, this script finds the largest unobstructed wall (“key wall”) and uses AnchorPrefabSpawner to place a prefab on that anchor.
using UnityEngine;
using Meta.XR.MRUtilityKit;
public class KeyWallFrameSpawner : MonoBehaviour
{
[Tooltip("Reference your pre-configured AnchorPrefabSpawner")]
public AnchorPrefabSpawner spawner;
// Call this method from the MRUK SceneLoadedEvent
public void OnSceneLoaded()
{
// 1. Find the 'key wall' anchor (the largest unobstructed wall)
Vector2 wallScale;
var keyWall = MRUK.Instance.GetCurrentRoom().GetKeyWall(out wallScale);
// 2. Spawn a single prefab on that anchor
spawner.SpawnPrefab(keyWall);
}
}
Related Samples
Virtual Home
This sample uses Spawner_VirtualHomeFurniture and AnchorPrefabSpawner to place VH_‑prefixed furniture on semantic anchors. Beds and couches auto‑face away from walls, and four plant variants are randomly chosen. Meshes resize with GridsliceResizer to keep features (e.g., table legs) square.
FindSpawnPositions selects random valid points on specified anchor surfaces like floors, vertical walls, or volumes, and spawns your prefab. It can perform physics overlap checks to ensure objects don’t collide when placed.
Configuration
SpawnOnStart: Begin spawning in Start().
SpawnObject: The prefab to instantiate.
SpawnAmount: Total instances to place.
Labels: Array of MRUKAnchor.SceneLabels (e.g., Floor, Wall).
SpawnLocation: Choose AnySurface, VerticalSurfaces, OnTopOfSurfaces, etc.
CheckOverlaps: Enable Physics.OverlapBox using OverlapLayerMask.
MaxIterations: Limit retries to avoid infinite loops.
SurfaceClearanceDistance: Minimum clearance from existing colliders.
Sample Usage
This script configures and runs a FindSpawnPositions component to randomly place a specified number of prefabs on floor surfaces while optionally avoiding overlaps. It shows how to modify its properties at runtime.
using UnityEngine;
using Meta.XR.MRUtilityKit;
public class ScatterOnFloor : MonoBehaviour
{
[Tooltip("Drag your FindSpawnPositions component here")]
public FindSpawnPositions spawner;
[Tooltip("Which semantic surfaces to spawn on (e.g. Floor)")]
public MRUKAnchor.SceneLabels[] labels = new[] { MRUKAnchor.SceneLabels.Floor };
[Tooltip("How many objects to spawn")]
public int spawnAmount = 10;
[Tooltip("Retry up to this many times to avoid overlaps")]
public int maxIterations = 50;
[Tooltip("Check physics overlaps before placing")]
public bool checkOverlaps = true;
// Call this method from the MRUK SceneLoadedEvent
public void OnSceneLoaded()
{
// Configure spawner with clear, descriptive fields
spawner.Labels = labels;
spawner.SpawnAmount = spawnAmount;
spawner.MaxIterations = maxIterations;
spawner.CheckOverlaps = checkOverlaps;
// Begin spawning once the scene model is ready
spawner.StartSpawn();
}
}
Related Samples
FloorZone
This sample uses three FindSpawnPositions instances to locate small, medium, and large floor areas, spawning circles that never intersect walls or furniture. Colliders are provided by two EffectMesh instances (with Colliders enabled), and the scene script calls CreateMesh() before StartSpawn() on SceneLoadedEvent to ensure correct ordering.
This sample demonstrates five FindSpawnPositions configurations, floating cubes, red wall tiles, green floor tiles, light‑green surface tiles, and blue ceiling tiles, using EffectMesh colliders first, then calling StartSpawn() on SceneLoadedEvent for each spawner.
For pinpoint control, cast a ray from a controller into the scene mesh colliders and instantiate at the hit point. Ensure your SceneMesh anchor has a MeshCollider (or use EffectMesh with colliders enabled) on a dedicated layer.
Setup Colliders
Add a MeshCollider to your global SceneMesh GameObject
Or enable Add Colliders on the EffectMesh prefab
Assign those GameObjects to a sceneMeshLayer for filtering
Sample Usage
using UnityEngine;
using Meta.XR.MRUtilityKit;
public class SceneMeshPlacer : MonoBehaviour
{
public Transform controller;
public GameObject prefabToPlace;
public LayerMask sceneMeshLayer;
void Update()
{
if (OVRInput.GetDown(OVRInput.RawButton.RIndexTrigger))
{
var ray = new Ray(controller.position, controller.forward);
if (Physics.Raycast(ray, out var hit, 100f, sceneMeshLayer))
{
Instantiate(prefabToPlace, hit.point, Quaternion.LookRotation(hit.normal));
}
}
}
}