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.