MRUK) SceneNavigation component with Unity’s NavMesh system to enable AI character navigation within a user’s physical room. An animated character named Breeze navigates to randomly placed apple targets on the generated NavMesh, picks them up, and eats them — all while pathfinding around real-world furniture.MRUK scene dataMRUK Sample repository from GitHub. Open the project in Unity and navigate to Assets/MRUKSamples/NavMesh/NavMesh.unity to open the sample scene. Build and deploy to your Meta Quest device following the instructions in the sample README. After launching, Breeze begins navigating to apple targets that spawn on your room’s floor.| File / Scene | What it demonstrates | Key concepts |
|---|---|---|
Scripts/NavMeshSampleController.cs | Scene controller with global mesh toggle | Hand trigger input, navigation mode switching |
NavMeshComponents/ToolkitScripts/NavMeshAgentController.cs | AI agent behavior and random target generation | Area-weighted random point selection, room boundary validation |
Scripts/NavMeshCharacterController.cs | Character animation and eating behavior | Animation state machine, velocity-based animation |
prefabs/SceneNavigation.prefab | MRUK SceneNavigation configuration | Floor-based navigation, furniture as obstacles |
prefabs/AppleWithCollider.prefab | Interactive target object | Collision detection for pickup |
Scripts/WireCubeOnBoundingBoxes.cs | Debug visualization for EffectMesh bounds | EffectMesh object iteration, LineRenderer integration |
MRUK scans your physical room and generates a NavMesh on floor surfaces, treating furniture and other obstacles as non-navigable areas. The character Breeze spawns and navigates to a randomly generated apple target on the floor, avoiding real-world furniture. After reaching the apple, Breeze plays a pickup animation, eats the apple with a particle effect, and a new target spawns. Press either hand trigger to toggle between room-mesh mode (navigation constrained to the current room) and global-mesh mode (navigation across multiple rooms if available). Press A, X, or Space (in editor) to force generation of a new target position.MRUK finishes loading room data. The sample configures floor surfaces as navigable and furniture as obstacles in the SceneNavigation.prefab, eliminating the need for pre-baked navigation data. See the SceneNavigation component reference for configuration details.NavMesh.CalculateTriangulation() to retrieve mesh geometry, computes the area of each triangle, selects a triangle weighted by area, and generates a random point using barycentric coordinates. This approach avoids clustering targets in small NavMesh regions.SetNewDestination() method in NavMeshAgentController.cs calls room.IsPositionInRoom(newPos, false) to confirm the target lies within physical room boundaries. If validation fails, the position resets to Vector3.zero and the agent navigates to the room origin instead.SceneNavigation.ToggleGlobalMeshNavigation(useGlobalMesh) to switch modes and refreshes the debug visualization accordingly. Global-mesh mode enables navigation across multiple rooms when connectRoomsInNavMesh is enabled on the SceneNavigation component.PickUp() and EatObject() methods in NavMeshCharacterController.cs are invoked by animation events rather than script polling. The character’s movement speed (NavMeshAgent.velocity.magnitude) drives the “Moving” animator parameter for smooth walk-to-idle transitions.NavMesh.SamplePosition() to let users manually place apples on valid NavMesh surfaces.