Save products you love by clicking the heart icon.
We use privacy-friendly analytics (Plausible + Umami) to understand how visitors use this site. No analytics are loaded without your consent. Privacy Policy
A comprehensive introduction to virtual reality covering computer graphics fundamentals, stereoscopic vision, VR history, device categories, motion tracking, and the reality-virtuality continuum.
Optimizing AI inference for XR devices — model quantization, NPU acceleration, hierarchical serving, bandwidth optimization for real-time 60fps rendering.
Unity is the most popular engine for XR development. This guide covers setting up projects for both Meta Quest and Apple Vision Pro.
Window → Package Manager → Unity Registry
Install:
- XR Plugin Management
- XR Interaction Toolkit
- OpenXR Plugin
- XR Hands
```text
## Meta Quest Setup
### XR Plugin Configuration
```text
Edit → Project Settings → XR Plug-in Management
✓ Oculus
✓ OpenXR (optional, for cross-platform)
```text
### Quest Features
```text
Edit → Project Settings → XR Plug-in Management → Oculus
✓ Shared Depth Buffer
✓ Low Overhead Mode (optional)
✓ Hand Tracking Support
✓ Passthrough Support
```text
### Build Settings
```text
File → Build Settings
Platform: Android
Texture Compression: ASTC
Graphics APIs: OpenGLES3 + Vulkan
```text
### Android Manifest
Add to `Assets/Plugins/Android/AndroidManifest.xml`:
```xml
<uses-feature android:name="android.hardware.vr.headtracking" />
<uses-permission android:name="com.oculus.permission.HAND_TRACKING" />
```text
## Apple Vision Pro Setup
### Requirements
- Unity 2023.2.4f1+
- Xcode 15.2+
- visionOS SDK
### XR Plugin Configuration
```text
Edit → Project Settings → XR Plug-in Management
✓ Apple visionOS
```text
### Build Settings
```text
File → Build Settings
Platform: iOS (visionOS)
Architecture: ARM64
```text
### Required Capabilities
In Xcode project settings:
- ARKit capability
- Hand Tracking capability
## XR Interaction Toolkit
### Basic Setup
```csharp
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class XRSetup : MonoBehaviour
{
void Start()
{
var xrOrigin = FindObjectOfType<XROrigin>();
var locomotion = xrOrigin.GetComponent<ActionBasedContinuousMoveProvider>();
}
}
```text
### Grab Interactable
```csharp
using UnityEngine.XR.Interaction.Toolkit;
public class GrabbableItem : XRGrabInteractable
{
protected override void OnSelectEntered(SelectEnterEventArgs args)
{
base.OnSelectEntered(args);
// Object grabbed
}
protected override void OnSelectExited(SelectExitEventArgs args)
{
base.OnSelectExited(args);
// Object released
}
}
```text
## Hand Tracking
### Enable Hand Tracking
```csharp
using UnityEngine.XR.Hands;
public class HandTrackingExample : MonoBehaviour
{
XRHandSubsystem handSubsystem;
void Start()
{
var manager = XRGeneralSettings.Instance?.Manager?.activeLoader?.GetLoadedSubsystem<XRHandSubsystem>();
handSubsystem = manager;
}
void Update()
{
if (handSubsystem != null)
{
handSubsystem.TryUpdateHands(XRHandSubsystem.UpdateType.Dynamic);
var leftHand = handSubsystem.leftHand;
var thumbTip = leftHand.GetJoint(XRHandJointID.ThumbTip);
if (thumbTip.TryGetPose(out var pose))
{
transform.position = pose.position;
}
}
}
}
```text
### Gesture Detection
```csharp
public class PinchDetector : MonoBehaviour
{
public float pinchThreshold = 0.02f;
public bool IsPinching(XRHand hand)
{
var thumbTip = hand.GetJoint(XRHandJointID.ThumbTip);
var indexTip = hand.GetJoint(XRHandJointID.IndexTip);
if (thumbTip.TryGetPose(out var thumbPose) &&
indexTip.TryGetPose(out var indexPose))
{
float distance = Vector3.Distance(thumbPose.position, indexPose.position);
return distance < pinchThreshold;
}
return false;
}
}
```text
## Passthrough (Meta Quest)
### Enable Passthrough
```csharp
using UnityEngine.XR.Management;
using UnityEngine.XR;
public class PassthroughController : MonoBehaviour
{
OVRPassthrough passthrough;
OVRManager ovrManager;
void Start()
{
ovrManager = FindObjectOfType<OVRManager>();
passthrough = gameObject.AddComponent<OVRPassthrough>();
passthrough.Enable();
}
public void SetPassthroughEnabled(bool enabled)
{
if (enabled)
passthrough.Enable();
else
passthrough.Disable();
}
}
```text
## Room Setup (Vision Pro)
```csharp
using UnityEngine.XR.ARKit;
public class RoomSetupController : MonoBehaviour
{
ARKitSessionSubsystem arKitSession;
void Start()
{
arKitSession = XRGeneralSettings.Instance?.Manager?.activeLoader?.GetLoadedSubsystem<ARKitSessionSubsystem>();
}
void RequestRoomMapping()
{
if (arKitSession != null)
{
arKitSession.RequestRoomMapping();
}
}
}
```text
## Build and Deploy
### Meta Quest
```bash
# Build APK
File → Build Settings → Build
# Deploy via ADB
adb install -r build.apk
# Or use Oculus Developer Hub
```text
### Apple Vision Pro
```bash
# Build for device
File → Build Settings → Build And Run
# Or build Xcode project
File → Build Settings → Build (creates .xcodeproj)
# Open in Xcode → Select visionOS target → Deploy
```text
## Conclusion
Unity XR development requires platform-specific setup but shares common interaction patterns. Start with XR Interaction Toolkit, add platform-specific features as needed.