One product, several public touchpoints
The primary immersive build targeted Meta Quest 2 and Quest 3, while OpenXR supported a desktop PC version installed in the fan zone for people who wanted to explore the race environment on site. A separate racing mini-game extended the activation to mobile and additional fan-zone stations. That made cross-platform input, UI scaling, performance budgets and deployment repeatability part of the product problem—not post-launch polish.
High-resolution immersive streaming
The experience worked with very high-resolution panoramic race media—approximately 8K across a roughly 220-degree field of view—using AVPro Video on standalone hardware. Source resolution, decoded texture cost and the headset eye buffer were separate constraints, so delivery involved balancing codec support, angular detail, projection geometry, foveation, MSAA and the number of active decoders rather than assuming an 8K source automatically produced an 8K visual result.
Decode once, present many race views
A matrix feed allowed one decoded video texture to be divided into multiple source rectangles and mapped across team and camera panels. This reduced network and decoder overhead compared with running every view as an independent stream, but introduced production risks around UV crops, tile ordering, aspect ratio, orientation, fallback states and encoder-layout changes. Playback state and race telemetry also needed a shared timeline so the visual story did not drift away from the live event.
Controllers, hands, gaze and world-space UI
The project evolved across legacy gaze handlers, OVRInput, Unity EventSystem behaviour, the newer Input System and Meta Interaction SDK rays. Those systems could otherwise process the same action twice—or disagree about coordinate space. The engineering challenge was to move toward one authoritative pointer route for buttons, sliders and draggable panels while retaining OVRInput for global shortcuts, passthrough controls and driving input.
A seek bar that understood live and recorded video
Seeking was not a conventional desktop-slider problem. Programmatic playback updates could trigger user-seek callbacks, while XR pointer positions arrived in screen or raycast coordinates that did not automatically match a curved world-space canvas. Stable behaviour required separating playback-driven updates from user intent, using no-notify value changes, and converting pointer raycasts into the slider's local coordinate space. Live windows, video-on-demand, hover previews and suggested-time states added further edge cases.
Making broadcast panels feel physically stable
Movable video windows exposed transform jitter whenever ray following, easing tweens, thumbstick dolly controls, parent transforms or physics attempted to own the same object in one frame. The robust interaction model used one controller-relative grab offset: controller movement positioned the panel, thumbstick depth changed the offset, and yaw input changed a rotation offset. That single-owner principle mattered more than whether the grabbed object was a canvas or detailed mesh.
Passthrough, curved UI and compositor layers
Passthrough introduced a rendering path beyond ordinary Unity camera sorting. Underlay and overlay configuration, background alpha, transparent materials, curved-canvas geometry, video surfaces and Meta compositor layers all affected the final result. Debugging therefore crossed Unity render queues, URP material behaviour and headset composition rather than relying on a single sorting-layer change.
Routing race audio into the spatial mix
AVPro audio only became spatially controllable when decoder output passed through a Unity AudioSource and the Meta XR spatializer instead of going directly to the Android audio path. Race sound also benefited from being treated as layers—engines, circuit ambience, crowd, commentary and UI—rather than positioning an entire stereo broadcast as one point source.
Build engineering for Quest and event PCs
Production delivery crossed Unity, OpenXR and Meta SDK versions, Android manifests, Gradle templates, IL2CPP stripping, graphics APIs and native media plugins. Diagnosing the final package meant inspecting the merged manifest and built APK or AAB rather than trusting one editor field. Runtime investigation also covered missing component references, onboarding-state errors and the cost of initialising several native video players together on memory-constrained devices.
Lead development across product and platform
I was responsible for connecting these systems into an experience that non-technical visitors could understand immediately. That included Unity and C# implementation, XR interaction design, live and recorded media behaviour, team-feed presentation, spatial UI, Quest performance, OpenXR desktop delivery, fan-zone readiness and the practical debugging required when broadcast, device and event constraints met in one product.