Optimize Unity Meta Quest VR game performance with AI
Updated: May 5, 2026
Your slash game is functional, but you don’t yet know whether it holds the crucial 72fps on Quest. This tutorial guides you through measuring actual performance on the headset, identifying the bottlenecks consuming your frame budget, and resolving those issues. You use the same AI workflow as in previous tutorials, but this time focused on performance optimization rather than feature development.
Open a terminal, navigate to your Unity project folder, and run claude. Send all prompts below in that Claude Code session.
Step 1: Capture a performance trace
Your game looks and feels right, but the Quest’s mobile GPU has a tight frame budget. The dissolve shader, energy blade, and mesh slicing you added in the previous tutorial all cost something. The only way to know the real cost is to measure it on the headset.
Play your slash game on your headset for 30 to 60 seconds. Trigger some combo chains and let the difficulty ramp up.
Tip: Run hzdb device configure-testing setup first to put your Quest in a testing-friendly state. It disables animations and keeps the screen awake for more consistent traces. Run hzdb device configure-testing restore when you’re done testing.
While the game is running, open your terminal and run:
This captures a 10-second Perfetto trace from the Quest, including CPU/GPU frame timing, rendering stats, and system activity. The -o flag names the session so you can reference it in later steps.
Verify: A trace is saved with session ID before_optimization and the file path is printed in your terminal.
Tip: To open the raw trace in Perfetto’s web UI, run hzdb perf open before_optimization. If you see a port 9001 conflict, run lsof -i :9001 to check what’s using it. If it’s a previous Perfetto server, stop it and retry. If it’s the Unity MCP, quit it with Ctrl+C first — you can restart it after the hzdb perf commands finish.
Step 2: Analyze the trace
You have a raw trace file with thousands of data points about what your Quest was doing during those 10 seconds. Instead of opening it in a trace viewer and reading it yourself, let Claude do the analysis. This prompt asks Claude to focus on the top bottlenecks rather than a full dump, so you get actionable results.
Prompt
I captured a Perfetto trace with session ID `before_optimization` while playing my slash game on Quest. Are any frames missing the 72fps target? What are the top 3 things eating the most frame budget? Break it down by GPU vs CPU.
Behind the scenes, the hz-perfetto-debug skill from the agentic-tools plugin reads the trace. The skill runs hzdb perf analyze-trace to query trace_processor for frame timing distributions, GPU render pass costs, thread scheduling, and bottleneck detection. This is a deterministic analysis of what actually happened on your hardware, not Claude guessing from training data. You can also run it directly in a separate terminal to see the raw analysis yourself:
hzdb perf analyze-trace before_optimization
Look for these patterns in the results:
Frame times above ~13.9 ms indicate dropped frames.
Draw calls above ~100 per frame suggest batching issues.
GC allocations during gameplay mean something is creating objects every frame.
GPU-bound means shaders are too expensive.
CPU-bound means scripts or physics are the bottleneck.
If your game is already hitting 72fps consistently, there’s almost always something to optimize, and the workflow is the same either way.
Verify: Claude identifies specific frames, timings, and bottleneck categories from your trace data.
Step 3: Review code and pick fixes
The trace tells you where the budget is going: a GPU bottleneck, a CPU spike, or GC pressure. Now let Claude look at the actual code to tell you why, and pick what to fix first. The features you added in the previous tutorial (dissolve shader, energy blade, runtime mesh slicing) are powerful but expensive on mobile hardware.
Prompt
Based on that trace analysis, review the slash game code for anything that's wasting performance on Quest. The dissolve shader, energy blade, and mesh slicing are probably the expensive parts. Between the trace data and the code, what are the top 2 fixes I should focus on first? Consider both the steady-state GPU cost and the worst-case frame spikes.
This flags VR-specific anti-patterns: things that work fine on PC but tank frame rate on Quest’s mobile GPU. Claude connects the trace data (where the budget goes) with the code (why it goes there) and recommends the highest-impact fixes.
Once Claude tells you the top bottleneck, you can cross-reference with Meta’s official optimization docs:
Replace the search query with whatever Claude identified. This gives you Meta’s recommended fix alongside Claude’s analysis, which is useful when you want to double-check or go deeper.
Verify: Claude recommends specific fixes with estimated impact, referencing both the trace data and actual code files.
Step 4: Apply the fixes
Now apply the two fixes Claude recommended. The exact changes depend on what your trace and code review found. Here’s roughly what to expect.
The first fix is usually a shader optimization. Claude simplifies the most expensive shader, reducing per-pixel computation and removing unnecessary overdraw.
The second fix is likely a memory optimization: pooling objects or reusing buffers to eliminate the GC spikes that cause the worst-case frame hitches.
Treat these as illustrative examples, not predictions for your project.
Prompt
Apply both fixes. For each one, tell me what you changed and what improvement you expect.
Verify: Code compiles, and the game still plays correctly in the Unity Editor.
If a fix breaks something: “The blade looks wrong after the shader change. Revert and try a less aggressive simplification.”
Step 5: Re-capture and compare
Time to close the loop. Comparing traces is how you confirm the fix actually helped and didn’t introduce a new problem. Build the optimized version, deploy it to Quest, capture a fresh trace, and compare. This is the core performance workflow. You use it any time you add expensive features.
In the Unity Editor, press Ctrl+S (Mac: Cmd+S) to save your project.
Go to File > Build Settings > Build. Save to your Builds folder as SlashGame.apk.
In your terminal, install the build: hzdb app install ./Builds/SlashGame.apk.
Launch the app: hzdb app launch com.YourCompany.YourApp (find your app name in Edit > Project Settings > Player > Other Settings > Package Name).
If install fails: Run export HZDB_ADB_PATH=$(which adb) and retry. This handles the case where adb devices shows your Quest but hzdb app install doesn’t.
Play again for 30 to 60 seconds, then capture another trace in your terminal (the first trace is safe because it has its own session ID from Step 1):
This saves the new trace under the session ID after_optimization. You now have two session IDs — before_optimization and after_optimization — that you can pass to hzdb perf compare.
Now ask Claude to compare. Under the hood, Claude uses hzdb perf compare to diff the two traces, showing exactly what improved, what regressed, and by how much.
Prompt
I captured a new trace with session ID `after_optimization` after applying the fixes. Compare it against the original session `before_optimization`. Did frame times improve? Are the GPU or GC spikes reduced? Show me before/after numbers for the top issues.
The comparison shows what improved, what regressed, and what to fix next.
Verify: Frame times are more consistent, with few or zero frames above ~13.9 ms. Your before/after numbers may not show dramatic improvement. Thermal throttling, different gameplay intensity, and GPU clock states all affect traces and performance.