October 20 2025
Myth: “The Unity Profiler shows everything.” Reality: It shows what’s instrumented. Sampling profilers reveal the rest.
You’ve got a Windows standalone build on a typical desktop machine. Players feel hitches, but your Editor profiler looks calm. You need whole‑process visibility, engine and scripts, without touching code.
You prep a build with symbols, attach Very Sleepy, and the call stacks start drawing you a map from PlayerLoop → render path → your MonoBehaviour.Update(). Now you know where to dig.
GameAssembly for your scripts; UnityPlayer/graphics runtime for engine) to separate concerns.Sampling profilers give you a view that doesn’t depend on where markers exist. That’s how you spot the engine work your scripts provoke and the native calls your markers didn’t cover.
Business line: Seeing true hot paths earlier shortens debug cycles and protects retention at launch.
If you only watch instrumentation, you optimize what you can already see and miss the work that actually costs. That’s how teams spend sprints on the wrong culprits, ship regressions, and invite churn.
There are two profiling families here:
Grounded takeaways: • “One is instrumentation‑based profiling and the other option is sampling based profiling.” • “Sampling profiling is easy to apply because you can do this with any process.” • “you need debugging symbols, the PDB files. Otherwise it’s going to only show you gibberish.”
Follow this once and you’ll reuse it across projects.
Edit → Project Settings → Player → Other Settings → Scripting Backend (IL2CPP)Edit → Project Settings → Player → Other Settings → Stack Trace InformationEdit → Project Settings → Player → Other Settings → Managed Stripping Level → MinimalFile → Build Settings → Development Build and enable Script Debugging for more verbose codegen.Edit → Project Settings → Player → Other Settings → Auto Graphics API (adjust as your other tools require).Grounded: “IL2CPP, stack trace information, mark everything, method name, file name, line number” and “Stripping level set it to minimal”.
GameAssembly*.pdb, Managed).Exclusive vs Inclusive refresher: Exclusive = time in the function’s own body. Inclusive = that plus all child calls.
Type “PlayerLoop” in the function table to jump to gameplay execution.
Look at the Module column:
GameAssembly → your scripts and IL2CPP‑generated code.UnityPlayer / graphics runtime → engine work.From PlayerLoop, step into Behaviour updates and locate your classes by name.
Even with sampling, you’ll still add markers where you own the code.
using UnityEngine;
public class ExampleHotspot : MonoBehaviour
{
void Update()
{
UnityEngine.Profiling.Profiler.BeginSample("ExampleHotspot.Update");
// ...your logic...
UnityEngine.Profiling.Profiler.EndSample();
}
}Use this to enrich the Editor profiler; rely on sampling to see beyond it.
PlayerLoop, then branch out.In the next post, we dig into Superluminal for Unity , Fast Hot‑Path Hunting with Filters & Histograms , read it here.
If your studio could use some help, we offer Unity consulting services here
Grab the Performance Checklist, turn captures into a prioritized fix list.
https://thegamedev.guru/unity-performance-checklist/
We help teams move from “we think it’s fine” to “we know it’s fixed.”
Ruben (TheGameDev.Guru)