Develop

Bouncing Ball sample overview

Updated: May 6, 2026

Overview

This sample demonstrates virtual balls physically interacting with your real-world environment using the Mixed Reality Utility Kit (MRUK) for Unity. The sample integrates Unity physics with MRUK’s Scene API through declarative configuration, requiring no MRUK API calls in your scripts.

What you will learn

  • How MRUK generates collision meshes from physical room geometry (walls, floors, furniture)
  • Use Unity’s standard physics system with MRUK-generated colliders
  • Implement grab-and-throw mechanics using controller input and velocity tracking
  • Implement dynamic visibility based on scene geometry occlusion
  • Configure prefabs for physics-based mixed reality interactions

Requirements

Hardware: Meta Quest device with passthrough capability
Development environment: Unity with MRUK package installed
For platform setup, SDK versions, and build prerequisites, see the MRUK Setup Guide.

Get started

Clone or download the Unity-MRUtilityKitSample repository. Open the project in Unity, navigate to the Assets/MRUKSamples/BouncingBall/BouncingBall.unity scene, and build to your Meta Quest device. For detailed build instructions and troubleshooting, see the sample’s README.

Explore the sample

Virtual balls bounce off your real room’s walls, floor, ceiling, and furniture. The sample provides two input modes: grab-and-throw (right trigger) to spawn and throw balls with controller motion, and shoot (right index trigger) to fire balls forward at high speed.
File / SceneWhat it demonstratesKey concepts
BouncingBall.unity
Scene setup with MRUK and controller input
OVRCameraRig, MRUK prefab, EffectMesh prefab, passthrough configuration
Prefabs/BouncingBall.prefab
Physics-enabled ball configuration
Rigidbody, SphereCollider, materials, audio sources
Scripts/BouncingBallMgr.cs
Controller input and ball spawning
Grab-and-throw, shoot mechanics, velocity tracking
Scripts/BouncingBallLogic.cs
Individual ball behavior
Visibility raycasting, physics integration, TTL-based destruction
Materials/
Visibility-based material swapping
Visible (teal) and hidden (muted red-brown) states
Audio/
Audio feedback for interactions
Bounce, pop, and load sound effects

Runtime behavior

When you run this scene, you see your physical environment through passthrough. Press the right trigger to spawn a teal ball at the controller position. While holding the trigger, the ball follows your controller. Release the trigger to throw the ball with the controller’s velocity — the ball bounces off your room’s walls, floor, and furniture. Press the right index trigger to shoot a ball forward at high speed. Each ball plays a bounce sound on collision and changes to a muted red-brown color when occluded by room geometry. After 5 seconds, each ball plays a pop sound and disappears.

Key concepts

Declarative MRUK integration

The sample contains zero direct MRUK API calls in C# scripts. The MRUK prefab loads room data from the Scene API, and the EffectMesh prefab generates MeshCollider components from room geometry. Standard Unity physics handles all ball-vs-room collisions. This pattern separates scene understanding (MRUK’s responsibility) from gameplay logic (your scripts’ responsibility). For the complete scene hierarchy, see BouncingBall.unity.

Grab-and-throw mechanics

The sample implements grab-and-throw by spawning a kinematic ball, moving it with the controller each frame, then switching to dynamic physics on release. The manager applies the controller’s world-space velocity to the ball using OVRInput.GetLocalControllerVelocity() transformed through the tracking space. This gives players intuitive physical control. For the complete implementation, see Scripts/BouncingBallMgr.cs.

Visibility-based occlusion feedback

Each ball raycasts from its position to the camera every frame. If room geometry blocks the ray, the ball swaps to a muted material to indicate occlusion. If the ray clears, the ball returns to its visible material. Both materials are opaque — the ball remains rendered, just tinted differently. For the complete occlusion logic, see Scripts/BouncingBallLogic.cs in the UpdateVisibility() method.

Continuous collision detection

The ball prefab uses Continuous Speculative collision detection on the Rigidbody, which prevents fast-moving objects from passing through thin surfaces. Combined with a small mass (0.0025 kg) and interpolation, this ensures smooth, realistic bouncing even when balls are thrown or shot at high speed. For the complete physics configuration, see Prefabs/BouncingBall.prefab.

Extend the sample

  • Modify the TTL value in BouncingBallLogic.cs to make balls persist longer or shorter.
  • Add new spawn modes by reading different controller buttons in BouncingBallMgr.cs — for example, left controller input or different throw speeds.
  • Replace the ball prefab with other physics objects (cubes, capsules) to experiment with different collision behaviors against room geometry.