Justin Park
Common issues and solutions when deploying Unity VR to Meta Quest from macOS, based on the Cemetree project deployment.
Symptom: Build fails with "Android SDK not found" despite Unity Hub showing Android Build Support installed.
Cause: macOS Gatekeeper blocks Android SDK components. Unity's automatic installation fails silently.
Solution:
1. Download manually:
Android Command Line Tools: https://developer.android.com/studio#command-line-tools-only
Extract to: ~/Library/Android/sdk/cmdline-tools/latest/
Android NDK: https://developer.android.com/ndk/downloads
Extract to: ~/Library/Android/sdk/ndk/[version]/
2. Bypass macOS security:
Each Android tool will be blocked on first run. For each blocked file:
System Settings → Privacy & Security
Click "Open Anyway" next to blocked app message
Confirm when prompted
Expect to do this 10-15 times for different executables (sdkmanager, adb, aapt, etc.).
3. Install SDK packages:
cd ~/Library/Android/sdk/cmdline-tools/latest/bin
./sdkmanager --licenses
./sdkmanager "platform-tools" "platforms;android-29" "build-tools;30.0.3"
4. Configure Unity:
Unity → Settings → External Tools:
Uncheck "Android SDK Tools Installed with Unity"
Android SDK: /Users/[username]/Library/Android/sdk
Android NDK: /Users/[username]/Library/Android/sdk/ndk/[version]
Symptom: Build freezes during shader compilation, eventually times out or produces black screen on Quest.
Cause: URP/Lit shaders generate too many variants for Quest's mobile compiler.
Solution:
Cancel build
Change all materials from URP/Lit to Mobile/Unlit (Supports Lightmap)
Window → Rendering → Lighting → Environment → Fog: Uncheck
Rebuild
Result: Build time drops from 15+ minutes to 2-5 minutes (85% reduction).
Prevention: Always use Mobile shaders for Quest projects. Never use URP/Lit or Standard shaders.
Symptom: Camera stays at world origin, controllers tracked but movement frozen.
Cause: Custom script overriding XR Origin position.
Solution:
Check for scripts like LockCameraPosition on XR Origin or Main Camera. Disable or remove any script that sets transform.position in Update(). XR Origin manages position automatically.
Correct Setup:
XR Origin at your desired start position (e.g., 1000, 30, 0)
Continuous Move Provider: Enable Fly, Use Gravity unchecked
No custom position-locking scripts
Symptom: Build warning about both old and new Input System active.
Cause: XR Interaction Toolkit requires new Input System, but project has both enabled.
Solution:
Edit → Project Settings → Player → Other Settings → Active Input Handling:
Change from "Both" to "Input System Package (New)"
Unity will restart
Click "Yes" when build warning appears if you haven't migrated yet.
Symptom: adb devices shows empty or "unauthorized".
Solution:
Enable Developer Mode in Meta Quest mobile app
Connect Quest via USB-C
Put on headset, accept "Allow USB Debugging" prompt
Check "Always allow from this computer"
Verify:
cd ~/Library/Android/sdk/platform-tools
./adb devices
Should show your Quest with "device" status.
If still not working:
./adb kill-server
./adb devices
Unplug and replug Quest, then retry.
Symptom: Users report "honed in circle" or disorienting vignette when moving.
Cause: Continuous Move Provider's comfort mode vignette.
Solution:
XR Origin → Continuous Move Provider:
Comfort Mode: Uncheck or reduce value
Note: Some users need this for motion sickness prevention.
Before building:
[ ] Android SDK path set in External Tools
[ ] Platform switched to Android
[ ] Oculus XR plugin enabled (Android tab)
[ ] Graphics API: OpenGL ES 3.0
[ ] Scripting Backend: IL2CPP
[ ] Target Architectures: ARM64 only
[ ] Mobile shaders used (not URP/Lit)
[ ] Quest connected: adb devices shows device
Delete Library folder in project root
Delete build output folder
Unity will reimport everything (takes 5-10 minutes)
Rebuild