Course contentsShow
← Unity Game Development
Lesson 147 of 8282. Scripting and LifecycleFree lesson

Optimizing Scripts Based on Profiler Data

Refactor inefficient scripts by applying optimization techniques like caching references or reducing update frequency based on actual Profiler performance metrics.

In this lesson, you will learn how to turn Profiler insights into actionable code improvements to eliminate performance bottlenecks.

When you run your game through the Unity Profiler (as we practiced in lesson 23), you often see "spikes" in the CPU graph. If a specific script is highlighted as a performance hog, it is usually because it is performing expensive operations unnecessarily inside the Update() method, which runs every single frame.

The "Caching" Strategy

A common bottleneck is calling GetComponent<T>() or GameObject.Find() inside Update(). These methods scan your scene or object hierarchy, which is extremely slow. Instead, use the Caching technique: fetch the reference once in Start() and store it in a variable.

Inefficient Code:

void Update() {
    // This scans the hierarchy 60+ times per second!
    GetComponent<Rigidbody>().AddForce(Vector3.up);
}

Optimized Code:

private Rigidbody rb;

void Start() {
    // Cache the reference once at startup
    rb = GetComponent<Rigidbody>();
}

void Update() {
    rb.AddForce(Vector3.up);
}

Reducing Update Frequency

If your Profiler data shows that a script is doing too much work, ask yourself: Does this really need to happen 60 times a second?

If you are checking for a distance between the player and an enemy, you don't need frame-perfect precision. You can use a Coroutine to "throttle" the logic to run only 5 or 10 times per second using WaitForSeconds. This significantly reduces CPU overhead without the player ever noticing a difference in gameplay. By combining Profiler data with these simple structural changes, you move from "it works" to "it runs smoothly."

Key Takeaway: Never perform expensive searches or heavy calculations inside Update() if you can calculate them once in Start() or spread the load across time using Coroutines.