AR/VR/XR Development
Platform Overview
| Platform |
SDK |
Target Devices |
| Unity XR |
XR Interaction Toolkit |
Quest, Vision Pro, PCVR, mobile |
| WebXR |
Three.js, A-Frame, Babylon.js |
Any WebXR browser |
| ARKit |
RealityKit, ARKit |
iPhone, iPad, Vision Pro |
| ARCore |
Sceneform, ARCore |
Android devices |
| Meta Quest |
Meta XR SDK |
Quest 2/3/Pro |
| Apple Vision Pro |
visionOS, RealityKit |
Vision Pro |
Unity XR
// XR Interaction Toolkit setup
using UnityEngine.XR.Interaction.Toolkit;
public class GrabbableObject : XRGrabInteractable
{
protected override void OnSelectEntered(SelectEnterEventArgs args)
{
base.OnSelectEntered(args);
// Object grabbed
}
protected override void OnSelectExited(SelectExitEventArgs args)
{
base.OnSelectExited(args);
// Object released
}
}
Unity XR Best Practices
- Target 72-120 FPS (platform-dependent) — frame drops cause nausea
- Use single-pass instanced rendering for stereo
- Bake lighting where possible, limit dynamic lights to 1-2
- Draw calls: <100 for mobile VR, <500 for PCVR
- Use LOD groups aggressively — user can't see distant detail in VR
WebXR
// Three.js WebXR
import * as THREE from 'three';
import { VRButton } from 'three/addons/webxr/VRButton.js';
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.xr.enabled = true;
document.body.appendChild(VRButton.createButton(renderer));
renderer.setAnimationLoop((time, frame) => {
if (frame) {
const session = renderer.xr.getSession();
const inputSources = session.inputSources;
// Handle controller input
}
renderer.render(scene, camera);
});
Apple Vision Pro (visionOS)
import SwiftUI
import RealityKit
struct ImmersiveView: View {
var body: some View {
RealityView { content in
let sphere = MeshResource.generateSphere(radius: 0.1)
let material = SimpleMaterial(color: .blue, isMetallic: true)
let entity = ModelEntity(mesh: sphere, materials: [material])
entity.position = [0, 1.5, -1]
content.add(entity)
}
.gesture(TapGesture().targetedToAnyEntity().onEnded { event in
// Handle tap on entity
})
}
}
XR Design Principles
- Comfort: Avoid artificial locomotion, use teleport or room-scale movement
- Interaction: Direct manipulation (grab, point) over abstract UI
- UI placement: World-space UI at comfortable distance (1-3m), avoid head-locked HUD
- Performance: Frame rate is non-negotiable — optimize ruthlessly
- Accessibility: Provide seated mode, adjustable scale, color-blind options
- Spatial audio: 3D audio for immersion and wayfinding (HRTF, ambisonics)
1---2name: ar-vr-xr3description: AR/VR/XR development with Unity XR, WebXR, ARKit, ARCore, Meta Quest SDK, and spatial computing. Use when building augmented reality, virtual reality, mixed reality applications, or spatial experiences.4---5
6# AR/VR/XR Development
7
8## Platform Overview
9
10| Platform | SDK | Target Devices |
11|----------|-----|----------------|
12| **Unity XR** | XR Interaction Toolkit | Quest, Vision Pro, PCVR, mobile |
13| **WebXR** | Three.js, A-Frame, Babylon.js | Any WebXR browser |
14| **ARKit** | RealityKit, ARKit | iPhone, iPad, Vision Pro |
15| **ARCore** | Sceneform, ARCore | Android devices |
16| **Meta Quest** | Meta XR SDK | Quest 2/3/Pro |
17| **Apple Vision Pro** | visionOS, RealityKit | Vision Pro |
18
19## Unity XR
20
21```csharp
22// XR Interaction Toolkit setup
23using UnityEngine.XR.Interaction.Toolkit;
24
25public class GrabbableObject : XRGrabInteractable
26{
27 protected override void OnSelectEntered(SelectEnterEventArgs args)
28 {
29 base.OnSelectEntered(args);
30 // Object grabbed
31 }
32
33 protected override void OnSelectExited(SelectExitEventArgs args)
34 {
35 base.OnSelectExited(args);
36 // Object released
37 }
38}
39```
40
41### Unity XR Best Practices
42- Target 72-120 FPS (platform-dependent) — frame drops cause nausea
43- Use single-pass instanced rendering for stereo
44- Bake lighting where possible, limit dynamic lights to 1-2
45- Draw calls: <100 for mobile VR, <500 for PCVR
46- Use LOD groups aggressively — user can't see distant detail in VR
47
48## WebXR
49
50```javascript
51// Three.js WebXR
52import * as THREE from 'three';
53import { VRButton } from 'three/addons/webxr/VRButton.js';
54
55const renderer = new THREE.WebGLRenderer({ antialias: true });
56renderer.xr.enabled = true;
57document.body.appendChild(VRButton.createButton(renderer));
58
59renderer.setAnimationLoop((time, frame) => {
60 if (frame) {
61 const session = renderer.xr.getSession();
62 const inputSources = session.inputSources;
63 // Handle controller input
64 }
65 renderer.render(scene, camera);
66});
67```
68
69## Apple Vision Pro (visionOS)
70
71```swift
72import SwiftUI
73import RealityKit
74
75struct ImmersiveView: View {
76 var body: some View {
77 RealityView { content in
78 let sphere = MeshResource.generateSphere(radius: 0.1)
79 let material = SimpleMaterial(color: .blue, isMetallic: true)
80 let entity = ModelEntity(mesh: sphere, materials: [material])
81 entity.position = [0, 1.5, -1]
82 content.add(entity)
83 }
84 .gesture(TapGesture().targetedToAnyEntity().onEnded { event in
85 // Handle tap on entity
86 })
87 }
88}
89```
90
91## XR Design Principles
92- **Comfort:** Avoid artificial locomotion, use teleport or room-scale movement
93- **Interaction:** Direct manipulation (grab, point) over abstract UI
94- **UI placement:** World-space UI at comfortable distance (1-3m), avoid head-locked HUD
95- **Performance:** Frame rate is non-negotiable — optimize ruthlessly
96- **Accessibility:** Provide seated mode, adjustable scale, color-blind options
97- **Spatial audio:** 3D audio for immersion and wayfinding (HRTF, ambisonics)