Prosto

Unity 6 MonoBehaviour Lifecycle: Awake, OnEnable, Start, and OnDisable 본문

Programing/Unity 3D

Unity 6 MonoBehaviour Lifecycle: Awake, OnEnable, Start, and OnDisable

Prosto 2026. 8. 1. 04:10
반응형

Prosto Unity

Original Korean post: May 1, 2017
Rewritten and verified: August 1, 2026
Tested with: Unity 6000.4.2f1
Korean edition: Awake, OnEnable, Start, OnDisable 호출 순서

I first wrote about Awake, Start, OnEnable, and OnDisable in Korean in 2017. When I recently went back to that post, the basic result was still correct: Unity called Awake, then OnEnable, and then Start.

The old explanation was too brief, though. Saying that “Awake runs when a script is first enabled” hides an important difference between an inactive GameObject and a disabled component. The description of FixedUpdate also needs to make it clear that physics steps and rendered frames do not run on the same clock.

Instead of translating the old article as it was, I created a separate Unity 6000.4.2f1 project and ran the lifecycle test again. This article is the updated result.

The short version

For an enabled component on an active GameObject, the order inside that component was:

Awake
OnEnable
Start
first Update

Disabling the component called OnDisable. Enabling it again called OnEnable, but did not call Awake or Start a second time.

Initial activation: Awake → OnEnable → Start → Update ...
Disable: OnDisable
Re-enable: OnEnable → Update ...
Destroy: OnDisable → OnDestroy

Awake OnEnable Start order in the 2017 Unity test

The original 2017 Console result. I observed the same initial order in Unity 6000.4.2f1.

A small script you can test

Attach this component to an empty GameObject and enter Play mode with the Console open. The script logs only the first Update call so that it does not fill the Console every frame.

using UnityEngine;

public sealed class LifecycleProbe : MonoBehaviour
{
    private bool loggedFirstUpdate;

    private void Awake()
    {
        Debug.Log($"{name}: Awake");
    }

    private void OnEnable()
    {
        Debug.Log($"{name}: OnEnable");
    }

    private void Start()
    {
        Debug.Log($"{name}: Start");
    }

    private void Update()
    {
        if (loggedFirstUpdate)
            return;

        loggedFirstUpdate = true;
        Debug.Log($"{name}: first Update");
    }

    private void FixedUpdate()
    {
        // Put physics work, such as applying forces to a Rigidbody, here.
    }

    private void OnDisable()
    {
        Debug.Log($"{name}: OnDisable");
    }

    private void OnDestroy()
    {
        Debug.Log($"{name}: OnDestroy");
    }
}

When does Awake actually run?

Unity calls Awake once during the lifetime of a script instance. It is a good place to cache components with GetComponent and prepare state that belongs to the component itself.

The part that is easy to miss is that the component's enabled checkbox and the GameObject's active state are different things.

  • If the GameObject is active but the component is disabled, Awake still runs. OnEnable and Start wait until the component is enabled.
  • If the GameObject itself is inactive, Awake waits as well. The first activation then produces Awake → OnEnable → Start.

This is the main correction to the wording in my 2017 article. Awake is not simply a callback that runs every time a script is enabled.

Treat OnEnable and OnDisable as a pair

OnEnable runs whenever the component becomes active and enabled. OnDisable runs when the component is disabled or its GameObject becomes inactive. Unity also documents OnDisable during destruction, scene unloading, and domain reloads.

A practical use is event registration. If a component subscribes to an event in OnEnable, it can unsubscribe in OnDisable. Keeping the two operations together helps prevent duplicate subscriptions when an object is enabled more than once.

Start runs later, but it is not a universal ordering system

Start runs once and always after the same component's Awake. During the initial scene load, Unity finishes the scene objects' Awake calls before it begins their Start calls. The familiar pattern of preparing A in A.Awake and reading it from B.Start can therefore still be useful.

That guarantee has limits. An object instantiated later can appear after other objects have already completed Start. Unity also does not guarantee which GameObject receives Awake first, or which receives Update first. A sequence that happens to look stable in the Editor should not become an invisible dependency.

Unity provides Script Execution Order and the [DefaultExecutionOrder] attribute when an explicit order is truly necessary. In smaller projects, I often find a visible bootstrap sequence easier to maintain than a growing list of global ordering rules.

Update and FixedUpdate use different clocks

Update runs once per rendered frame while the MonoBehaviour is enabled. Frame-rate-independent movement and timers normally use Time.deltaTime.

FixedUpdate belongs to the physics loop. Its interval comes from Time.fixedDeltaTime, which defaults to 0.02 seconds, or 50 physics steps per second. You can change that value in the Time settings or in code.

It does not run exactly once per rendered frame. Depending on the rendering speed and simulation needs, Unity can call FixedUpdate zero, one, or several times during a frame. This is why ordinary input is usually read in Update, while work such as Rigidbody.AddForce belongs in FixedUpdate.

What still holds from 2017?

The core observation survived: the initial order is still Awake → OnEnable → Start, followed by OnDisable when the component is disabled and OnEnable when it is enabled again.

The update is mostly about drawing the boundaries more carefully:

  • Awake runs once per instance, but an inactive GameObject delays it.
  • OnEnable and OnDisable can repeat as the object is toggled.
  • Start runs once and after the same component's Awake.
  • Unity does not guarantee the order of the same event function across different GameObjects.
  • The 0.02-second fixed timestep is a default, not a promise of one FixedUpdate call per rendered frame.

An old tutorial does not always need to be discarded. In this case, the basic principle was still useful. Running it again in a current Unity version made it much easier to see which parts deserved a more precise explanation.

Official Unity references

반응형
Comments