AR/VR
Unity for XR
Job Simulator on Quest, Beat Saber on Index, IKEA Place on iPhone - three completely different platforms, all built in Unity. Any XR studio today faces a choice: write against native Meta/Apple/Google SDKs and maintain three codebases, or adopt the Unity XR stack and build one application that targets everything. Between 2020 and 2024 Unity consolidated its packages (XRI, OpenXR, AR Foundation) into a single pipeline. 'Write once, run on every XR device' is not a marketing slogan but a concrete set of APIs that save months of development.
- **Job Simulator (Owlchemy Labs):** a single Unity project builds for Quest, PSVR2, SteamVR, and Pico. XRI and OpenXR ensure identical grab mechanics across platforms
- **IKEA Place / Houzz:** AR Foundation lets one team ship iOS and Android versions of furniture AR without maintaining two native projects
- **Bigscreen Beyond, Pico Neo, Quest 3:** new headsets arrive with OpenXR support, so Unity applications run on them out of the box without porting
XR Interaction Toolkit: Interactions out of the Box
Before 2020, every Unity XR project reinvented grab, teleport, and ray-pointer from scratch. Teams copied scripts from YouTube, hit bugs with two hands holding one object, and spent time on UI raycasting. In 2020 Unity released the XR Interaction Toolkit (XRI) - an official package with ready-made components: XRGrabInteractable, XRRayInteractor, XRSocketInteractor, locomotion, UI canvas integration. XRI runs on top of any XR provider (Oculus, OpenXR, Windows MR), so the same code builds for Quest, Vive, and PSVR2.
XRI architecture: Interactor (what interacts: hand, controller, gaze) and Interactable (what is interacted with: prop, UI, slot). XRInteractionManager is a singleton dispatcher that matches interactor to interactable via hover/select/activate events. Each Interactable declares which Interactor types it accepts. This system removed about 90% of the boilerplate code of earlier years.
What is the fundamental difference between XR Interaction Toolkit and a hand-written grab script?
OpenXR: One Backend for Every Headset
Before OpenXR, the choice of SDK was made at project start: Oculus SDK for Quest, OpenVR/SteamVR for Vive, Windows MR for HoloLens. Porting between them meant rewriting input mappings, controller models, and tracking. OpenXR (Khronos, 2019) is an open standard from the consortium behind Vulkan. One API, with extensions for device-specific features (eye tracking, hand tracking, passthrough). Unity 2021+ ships OpenXR as the primary provider; Meta, Valve, Microsoft, Sony, Pico, and ByteDance are compatible.
OpenXR input is abstracted through Interaction Profiles - descriptors of a controller in the form 'producer/profile/component', for example '/interaction_profiles/oculus/touch_controller'. The developer never writes code against a specific controller: an Action Map (Grab, Trigger, Teleport) is defined, and the runtime substitutes the appropriate button binding for the connected headset.
What exactly does OpenXR solve in cross-platform development?
VR Template: a Starter Project as a Contract
Unity VR Template is the official Unity Hub starter that builds against OpenXR and ships a ready scene: XR Origin with a camera offset, locomotion (continuous and teleport), snap-turn, two sample levels, and demo objects driven by XRI. The template is not academic but production-ready: teams adopt it as the contractual starting point of a project. Inside, XR Plugin Management, Input System Action Maps, and recommended render settings for Quest (single-pass instanced rendering, MSAA 4x, mobile HDR off) are already configured.
Key components of the VR Template: XR Origin (formerly XR Rig) is the scene root with the tracking space; Main Camera represents the head; Left/Right Controller GameObjects hold the hand poses. Continuous Move Provider and Snap Turn Provider implement locomotion. The Tunneling Vignette component reduces motion sickness during fast movement. The render pipeline is URP with XR rendering configured and post-processing disabled for performance.
Why do teams pick the VR Template instead of an empty 3D scene?
AR Foundation: ARKit and ARCore in One API
Apple ARKit (Swift, Objective-C) and Google ARCore (Java, Kotlin, C) are two independent AR platforms with different APIs. AR Foundation (Unity, 2018) is an abstraction package that lets AR logic be written once and built for iOS and Android. The architecture: ARSession manages the lifecycle, ARSessionOrigin defines the coordinate frame, and specialized tracked managers - ARPlaneManager, ARFaceManager, ARMeshManager, ARAnchorManager - subscribe to tracking events. Under the hood, each manager delegates work to native SDKs via the XR Plugin.
Trackable is the base abstraction of AR Foundation: anything the AR system detects in the real world (planes, faces, images, objects, point clouds). Each Trackable receives a unique TrackableId and a TrackingState (None/Limited/Tracking). The API is event-based: TrackablesChangedEventArgs contains added/updated/removed lists, allowing virtual content to be updated incrementally as tracking data is refined.
Since OpenXR and AR Foundation both exist, a single application can target VR and AR simultaneously
OpenXR covers VR headsets and MR devices with a dedicated compositor. AR Foundation is a separate stack for smartphone AR (ARKit/ARCore). These are different rendering pipelines, input models, and UX paradigms
A VR application runs in fullscreen stereo rendering with two controllers. Smartphone AR is monocular pass-through with touch input and a 'look through a window' behavior. Combining them is only possible on devices like Quest 3 (VR plus passthrough) or Apple Vision Pro - and even there the developer chooses immersive/shared space at the scene level
What does AR Foundation provide as an abstraction?
Key Takeaways
- **XR Interaction Toolkit** standardizes grab/teleport/UI raycast through the Interactor-Interactable contract - 90% of typical XR boilerplate is moved into the package.
- **OpenXR** replaces vendor SDKs with a single Khronos standard: one build runs on Quest, Index, Pico, and Vive through identical Action Maps.
- **VR Template** is a production-ready starter with configured XR Plugin Management, locomotion, and mobile VR render settings.
- **AR Foundation** abstracts ARKit and ARCore into one C# API: ARPlaneManager, ARRaycastManager, and ARAnchorManager work the same on iOS and Android.
Related Topics
The Unity XR stack unifies tracking, input abstractions, and cross-platform rendering.
- Introduction to VR and AR — Platform stacks implement the six-degrees-of-freedom and stereo-rendering model that drive XR
- Multiplayer XR — A networked XR session is built on top of Unity XR Origin and synchronizes controller poses between clients
Вопросы для размышления
- If OpenXR standardizes input and tracking, are native Oculus/Pico SDKs still needed? In which cases do teams deliberately abandon OpenXR for a vendor SDK?
- XR Interaction Toolkit owns interactions but not gameplay. Where is the boundary: what stays inside XRI and what belongs in project-specific code?
- AR Foundation requires the device to be on the ARCore Supported list. How does this affect the target audience and addressable market of a mobile AR application?
Связанные уроки
- arvr-12 — Previous lesson is the foundation for Unity XR
- arvr-14 — Unreal is the alternative engine - comparison is essential
- arvr-15 — Unity is a component of the XR system architecture
- ds-01-arrays — GameObject/Component is like data structures in ECS
- st-05-emergence — Unity scene is emergent behavior from components
- cg-01