Quick answer: Unity GPU Instancing enabled on a material but draw calls still per-mesh? Per-instance material modifications (sharedMaterial set to a clone) break batching — use MaterialPropertyBlock instead.

100 enemies use the same prefab but each got a distinct material instance for tint. Frame profiler shows 100 draw calls.

MaterialPropertyBlock

MaterialPropertyBlock mpb = new();
mpb.SetColor("_Color", tint);
renderer.SetPropertyBlock(mpb);

Per-renderer property without cloning the material. GPU Instancing batches all renderers using the same material.

Shader Must Support Instancing

Shader needs #pragma multi_compile_instancing and instanced uniforms via UNITY_ACCESS_INSTANCED_PROP. Standard shaders are set; custom shaders need explicit support.

Lightmap and Shadows

Per-instance lightmap UVs disable instancing. Static / dynamic lighting choice affects batching.

Profile Frame Debugger

Window → Frame Debugger. Each draw call shows its instance count. If you see 1-each, instancing didn’t engage; debug from there.

Verifying

Hundreds of instances draw in a handful of calls. Frame Debugger confirms instance counts > 1.

“Material clones break instancing. MaterialPropertyBlock for per-instance variation.”

If you need many per-instance properties, switch to GPU Instancing with shader properties array — faster than property blocks for high counts.