Keep the scene fast
Assets/
Scenes/
Arena.unity
Scripts/
Prefabs/
Project settings
you already havethis lesson adds
The arena ran at hundreds of frames a second when it was eleven objects on a grey floor. With a few hundred trees around it, it will not — unless you do the four things in this lesson.
A scene that runs at 12 FPS is not a scene, it is a screenshot. Four techniques cover most of the gap between 12 and 60.
Far objects get a simpler mesh. The player never sees the swap.
1. Measure before you fix anything
- 1
Open and look at the CPU and Rendering rows.
- 2
In the Game view Stats panel, read Batches and Tris — while walking the Knight around, not while standing still.
- 3
If CPU time is high → too many draw calls or too much script work. If GPU time is high → too many pixels, overdraw or heavy shaders.
2. LOD groups
- 1
Select a prop, Add Component → LOD Group.
- 2
Drag the high-poly mesh into LOD 0, a mid mesh into LOD 1, a low one into LOD 2.
- 3
Set the Culled band so the object disappears entirely when it is a few pixels tall.
- 4
Trees, buildings and rocks benefit most. Small pebbles are not worth the setup.
3. Cut the draw calls
Static Batching: tick Static on every object that never moves. Unity merges them into shared meshes at build time.
GPU Instancing: tick Enable GPU Instancing on the material of anything repeated hundreds of times. 500 identical rocks become one draw call.
Fewer materials means fewer batches. Two objects with the same material batch; the same objects with different materials do not.
Atlas your textures: one 2048 texture holding twelve props beats twelve 512 textures.
4. Occlusion culling
- 1
Frustum culling (not drawing what is off-screen) is automatic. Occlusion culling (not drawing what is behind a wall) is not.
- 2
Mark walls and buildings as Occluder Static, then .
- 3
Worth it for interiors and dense cities. Pointless for an open field where you can see everything.
5. Shorten the camera's reach
// Camera Far = 1000 by default. Most levels need 150.
Camera.main.farClipPlane = 150f;
// hide the ugly cut-off with fog
RenderSettings.fog = true;
RenderSettings.fogMode = FogMode.Linear;
RenderSettings.fogStartDistance = 90f;
RenderSettings.fogEndDistance = 145f;Per-layer culling distances
void Start()
{
float[] distances = new float[32]; // one entry per layer
for (int i = 0; i < 32; i++) distances[i] = 150f;
distances[LayerMask.NameToLayer("SmallProps")] = 35f; // pebbles vanish early
distances[LayerMask.NameToLayer("Grass")] = 25f;
Camera.main.layerCullDistances = distances;
}