Most indie Unity games do not fail because the art is “wrong.” They fail because the build is heavy, hitchy, or unplayable on the hardware players actually own.
This Unity performance checklist for indie games is a practical pass you can run before Steam page screenshots, playtests, and store submission — not a research paper.
Table of Contents
Profile before you guess
- Record a Player build with Unity Profiler or Frame Debugger — Editor numbers lie.
- Capture a 30–60s “worst” scene: combat, inventory open, streaming load, or dense VFX.
- Write down the top 3 costs (CPU main thread, GPU, GC spikes) before changing anything.
- Fix one bottleneck at a time and re-measure. Random toggles waste days.
CPU and gameplay code
- Kill empty
Update/LateUpdateon idle objects; prefer events and coroutines with clear exit conditions. - Cache component lookups. No
GetComponentin hot loops. - Replace per-frame LINQ and string concat in gameplay paths.
- Batch AI / perception: fewer agents thinking every frame beats smarter agents thinking constantly.
- Use Jobs/Burst only where you already measured a win — not as cargo cult.
Rendering and GPU
- Target a real platform budget (e.g. 1080p medium on a mid laptop / Steam Deck class).
- Reduce materials and variants. Atlas where it helps; avoid unique shaders per prop.
- Enable GPU instancing / SRP Batcher-friendly shaders; check Frame Debugger for unexpected breaks.
- LOD groups on characters and dense environment meshes; cull aggressively outdoors.
- Cap realtime lights and shadows. Prefer baked or mixed lighting for static worlds.
- Turn off unused post effects in builds players actually ship (depth of field, heavy bloom stacks).
Memory and GC
- Watch GC Alloc in Profiler during combat and UI opens — spikes feel like stutter.
- Pool frequent spawns (bullets, VFX, enemies, damage numbers).
- Avoid allocating arrays/lists every frame; reuse buffers.
- Audit texture sizes and compression (ASTC/DXT/ETC as platform requires). Mipmaps on 3D textures.
- Unload unused addressables/scenes; do not keep “just in case” worlds resident.
Audio, UI, and input
- Limit simultaneous voices; use mixers and prioritization so combat does not explode DSP cost.
- Compress large clips; streaming for long music beds.
- UI Toolkit / uGUI: avoid rebuilding huge canvases every frame; split static vs dynamic canvases.
- Disable idle UI objects instead of leaving heavy panels active off-screen.
- Input polling is cheap; input-driven allocation (new strings, new events each frame) is not.
Build and player settings
- Ship IL2CPP (or the platform default that matches your store) and test a Development Build only for diagnosis.
- Strip engine code / managed stripping level carefully; verify reflection-heavy plugins still work.
- Quality settings: expose Low/Medium/High that actually change shadow distance, MSAA, and particle budgets.
- Remove demo scenes, sample content, and unused Asset Store packages from the player.
- Measure cold start and first-scene load on a clean machine — first impressions matter.
Pre-ship smoke test
- 30 minutes of continuous play on target hardware with no thermal crash.
- Worst-case VFX + UI + AI scene stays within your FPS floor.
- No multi-second hitch when opening inventory / map / pause.
- Memory stable across a full level transition loop (watch for leaks).
- Controller + keyboard paths both feel responsive under load.
Related reading: Asset Store vs Package Manager, Controller & Input Assets, and our Top 100 Paid tools list.
Wrap-up
Performance is a product feature. Run this checklist early, again before trailer capture, and once more before submission. Players forgive rough art longer than they forgive stutter.
