Script Execution Order in Unity: The Hidden Timeline of Your Game
If you’ve ever wondered why one of your scripts runs before another, or why something that looks right in code still happens “too soon” or “too late” in the game, you’ve met one of Unity’s most misunderstood systems: Script Execution Order.
Every Unity project runs on a timeline. But it’s not just frames ticking by — there’s an internal sequence of events that determines exactly when your methods are called, which scripts get updated first, and how physics, rendering, and coroutines all fit into the same frame. Understanding this timeline is one of those “ah-ha” moments that instantly makes your debugging life easier.
The Big Picture: How Unity Thinks in Frames
At the heart of Unity’s engine is the game loop — a repeating cycle that runs once per frame. You can think of each frame like a single turn in your game’s heartbeat. Every time the loop runs, Unity handles input, updates objects, runs physics, renders the frame, and then starts over.
It’s easy to forget that Unity’s doing all of this in a very specific order — one that’s consistent every frame. The more you understand it, the more control you have over how your gameplay logic behaves.
Let’s take a walk through that order.
The Lifecycle of a MonoBehaviour
Every MonoBehaviour script you write in Unity participates in this execution order. These are the main methods Unity looks for and calls automatically, if they exist in your script:
Awake()OnEnable()Start()Update()FixedUpdate()LateUpdate()OnDisable()OnDestroy()
You’ve seen these before. But the real trick isn’t just knowing they exist — it’s understanding when they run and how they relate to each other.
Let’s break them down in context.
Awake and OnEnable: The Setup Phase
When a scene loads, Unity starts by creating all the objects that exist in it. As it does, it calls each script’s Awake() method.
Awake() runs before anything else — even before Start() — and it’s guaranteed to run once for each object when it’s first created (whether that’s on scene load or via Instantiate()).
Use Awake() for initialization that doesn’t depend on other objects being ready yet — like setting up references, loading data, or initializing state.
Immediately after Awake(), Unity calls OnEnable() for every script attached to active objects. This happens right away when an object becomes active, and again if you re-enable it later in the game.
OnEnable() is where you might register for events, subscribe to listeners, or enable runtime behavior that depends on the object being “live” in the scene.
Here’s the rule of thumb:
Awake: “I exist.”
OnEnable: “I’m active.”
Start: The Launch Point
After Unity finishes calling all the Awake() and OnEnable() methods in the scene, it calls each object’s Start() method — but only if that script is currently enabled.
That’s important: if a script is disabled when the scene loads, its Start() method won’t run until it’s enabled for the first time.
This is why some code that “should” initialize doesn’t always run when you expect. If you enable an object later in the game, its Start() runs then — not at scene load.
Use Start() for any setup that relies on other objects being initialized, because by the time it runs, every other Awake() has already fired.
If Awake() is construction, Start() is ignition.
Update: The Per-Frame Workhorse
Once everything is set up, Unity enters its main loop — the per-frame update cycle. This is where your game logic lives.
Each frame, Unity calls every active script’s Update() method. This is where most of your gameplay logic goes: input handling, timers, movement calculations, and state changes.
But not everything in Unity runs at the same time or at the same pace. Some systems (like physics) have their own update cycles that run on different schedules. That’s why Unity provides other update methods like FixedUpdate() and LateUpdate().
FixedUpdate: The Physics Cycle
FixedUpdate() runs on a fixed timestep, independent of your frame rate. By default, Unity calls it every 0.02 seconds (50 times per second), though you can change this in Project Settings → Time → Fixed Timestep.
This is where all the physics magic happens. Unity’s physics engine runs before each FixedUpdate() cycle, so it’s the right place for movement or forces that depend on physics consistency.
For example, if you’re moving a Rigidbody using AddForce(), do it in FixedUpdate() — not Update() — so your physics remain stable even if your frame rate fluctuates.
You can think of FixedUpdate() as running on the engine’s internal metronome, while Update() dances to the rhythm of your hardware.
LateUpdate: The Finishing Touch
After all Update() calls have finished for the frame, Unity calls LateUpdate(). It’s your final chance to adjust things before rendering happens.
This is where you handle logic that needs to happen after everything else — like following a player’s position with a camera, or syncing animations after movement.
Typical example:
Because LateUpdate() happens after Update(), it guarantees your camera moves after your player does. Without it, the camera might jitter or lag one frame behind.
The End of the Frame
After all your LateUpdate() calls finish, Unity starts wrapping up the frame. It processes rendering, draws the scene, and then runs a few more behind-the-scenes methods like OnRenderObject() and OnPostRender() for scripts that deal directly with graphics.
Then the frame ends, and the cycle starts again.
How Coroutines Fit In
Coroutines (IEnumerator methods that use yield return) get special treatment in Unity’s execution order. They’re processed alongside the Update cycle — specifically, after all Update methods have run but before LateUpdate.
Each time a coroutine yields, Unity pauses it and resumes it in a future frame based on what you returned:
yield return nullresumes next frameyield return new WaitForSeconds(1f)resumes after one secondyield return new WaitForEndOfFrame()runs after everything else in that frame, even after rendering
This makes coroutines a powerful tool for timing and sequencing events without blocking your main game loop.
The Complete Picture (Frame Flow Summary)
Here’s Unity’s rough per-frame timeline simplified:
How updates are processed, for both the physics loop and the frame loop
Quick note: When you see “Physics Sim” in that timeline, it refers to Unity’s physics simulation step — the part of the loop where the engine actually does the math. This is when it applies gravity, calculates collisions, resolves contact forces, and fires events like OnCollisionEnter(). It’s what happens after you apply forces or move rigidbodies in FixedUpdate(). Unity runs these physics passes on a steady rhythm (the fixed timestep), so your physics stay consistent even if your frame rate wobbles.
And on scene load:
Order of script execution before entering the game loop update cycles
Knowing where your code fits in this cycle is one of the best debugging tools you can have. It’s the difference between “Why does this happen a frame late?” and “Ah, that’s because Start() runs after Awake().”
Customizing Execution Order
Sometimes you have multiple scripts running Update(), and you need one to always execute before another. For example, you want your player input system to update before your movement system.
By default, Unity doesn’t guarantee the order that scripts of the same type execute. But you can control it in a few ways.
1. Project Settings → Script Execution Order
In Unity’s menu bar, go to Edit → Project Settings → Script Execution Order.
You’ll see a list where you can drag scripts up or down to change their global execution priority.
This method is handy for broad systems (like making your input manager run first), but it’s best to use sparingly. Too many forced orders can make dependencies fragile.
2. Runtime Dependencies
The cleaner approach is to use explicit dependencies in code. For example, have your movement script read data from your input system rather than assume it ran first. That way, your systems stay modular and testable.
3. Manual Control
For advanced cases, you can use events or manually invoke updates in a controlled order:
Controlling the order that systems get updated
This makes order explicit, though it’s more work to manage. The Tick() method isn’t something built into Unity — it’s just a naming convention many developers use when they want full control over update order. Think of it as a manual version of Update(). Instead of letting Unity decide when each script runs, you call each system’s Tick() yourself, in whatever order you choose. This makes your execution flow explicit, predictable, and easier to reason about in larger projects where dependencies between systems matter.
Debugging Timing Issues
If you’ve ever had an animation lag by one frame, or an object spawn slightly out of sync, it’s probably because something happened in the wrong part of the execution order.
Common culprits:
Initializing objects in
Start()that other scripts needed inAwake()Moving physics objects in
Update()instead ofFixedUpdate()Updating a camera in
Update()instead ofLateUpdate()Assuming
OnEnable()runs before another script’sAwake()
If something’s “off by one frame,” your fix probably isn’t more code — it’s moving code to the right part of Unity’s timeline.
A Practical Rule of Thumb
If you remember nothing else, remember this:
Use Awake for setup that doesn’t depend on anything else.
Use Start for setup that does depend on other scripts being ready.
Use Update for per-frame logic.
Use FixedUpdate for physics.
Use LateUpdate for camera and cleanup tasks.
That one guideline alone prevents about 80% of the timing bugs most Unity devs face.
Wrapping Up
Script execution order isn’t something you can ignore. It’s the silent director of your entire game, quietly dictating who speaks first and who speaks last every frame.
Once you understand how Unity’s timeline works, debugging becomes less of a guessing game. You start to see the flow of your code — how Awake feeds into Start, how Update drives the world forward, and how LateUpdate ties up the loose ends before rendering.
Unity may be event-driven, but under the hood, it’s pure choreography — and you’re the one conducting the orchestra.
Want to continue the discussion? Join us at the Sugar Shack Skool group.