Script Lifecycle

You never call Start or Update yourself. Unity calls them for you, at specific moments and in a fixed order. Knowing that order tells you where each piece of code belongs.

The order, simplified

A theater show. Unity is the stage manager with a script of cues, and your methods are actors waiting for their cue. Awake is the actor arriving backstage and getting into costume. Start is walking on stage right before the curtain rises, when everyone else is already in costume. Update is saying your line every time the stage manager points at you, once per frame, for the whole show. OnDestroy is leaving the building after the show. You never shout your own cue; you wait to be called.

Once, when the object is createdAwake()OnEnable()Start()before the first frameEvery frame (repeats)Physics loop (fixed rate)FixedUpdate()Physics simulation stepOnTrigger… / OnCollision…runs 0, 1 or several times per frameUpdate()Coroutines resume (yield null)Animation updateLateUpdate()Render the framenext frameWhen disabled or destroyedSetActive(false) or Destroy()OnDisable()OnDestroy()
The order Unity calls your methods. The physics loop runs as many times as needed to keep a steady 50 steps per second, so it can run several times in one frame or be skipped. Your per-frame code in Update (highlighted) always runs once per frame.

When the object is created (once):

  1. Awake(): the object exists. Set up references to your own components here.
  2. OnEnable(): the script was turned on. Subscribe to events here.
  3. Start(): runs just before this script's first Update. Every object's Awake has already run, so it is safe to talk to other objects.

Every frame (repeats):

  1. FixedUpdate(): runs at a fixed rate (50 times per second by default). May run 0, 1 or several times in a single frame. Put physics code here.
  2. Unity simulates physics, then calls OnTriggerEnter, OnCollisionEnter and similar callbacks.
  3. Update(): runs once per frame. Put input and most game logic here.
  4. Coroutines that did yield return null continue.
  5. Animations are updated.
  6. LateUpdate(): runs after every Update has finished. Good for cameras that follow something.
  7. The frame is drawn to the screen.

When the object goes away:

  1. OnDisable(): the script was turned off or the object is being destroyed. Unsubscribe from events here.
  2. OnDestroy(): the object is being destroyed (or the scene is closing).

Which method should I use?

MethodCalledUse it for
AwakeOnce, when the object loads. Runs even if the script component is disabled (as long as the GameObject is active).GetComponent calls, initializing your own variables
OnEnableEvery time the script becomes enabled / the GameObject becomes activeSubscribing to events, resetting state for reused (pooled) objects
StartOnce, before the first Update, only if the script is enabledCode that needs other objects to be set up already
FixedUpdateFixed time step (default every 0.02 s)Rigidbody forces and velocity
UpdateEvery frameInput, timers, non-physics movement, game logic
LateUpdateEvery frame, after all UpdatesCamera follow, anything that must react to where things ended up this frame
OnDisableWhen disabled or destroyedUnsubscribing from events, stopping sounds
OnDestroyWhen destroyedFinal cleanup

Example: seeing the order yourself

Attach this to a GameObject, press Play, then disable the GameObject and stop the game. Watch the Console.

using UnityEngine;

public class LifecycleLogger : MonoBehaviour
{
    void Awake()       { Debug.Log("1. Awake"); }
    void OnEnable()    { Debug.Log("2. OnEnable"); }
    void Start()       { Debug.Log("3. Start"); }

    void FixedUpdate() { if (Time.frameCount < 3) Debug.Log("FixedUpdate, frame " + Time.frameCount); }
    void Update()      { if (Time.frameCount < 3) Debug.Log("Update, frame " + Time.frameCount); }
    void LateUpdate()  { if (Time.frameCount < 3) Debug.Log("LateUpdate, frame " + Time.frameCount); }

    void OnDisable()   { Debug.Log("OnDisable"); }
    void OnDestroy()   { Debug.Log("OnDestroy"); }
}

Example: a camera that follows the player

The player moves in Update. If the camera also moved in Update, it might run before the player and lag one frame behind, which looks jittery. LateUpdate guarantees the player has already moved.

using UnityEngine;

public class FollowCamera : MonoBehaviour
{
    [SerializeField] private Transform target;
    [SerializeField] private Vector3 offset = new Vector3(0f, 5f, -8f);

    void LateUpdate()
    {
        if (target == null) return;
        transform.position = target.position + offset;
        transform.LookAt(target);
    }
}

Example: subscribing to events safely

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneListener : MonoBehaviour
{
    void OnEnable()
    {
        SceneManager.sceneLoaded += HandleSceneLoaded;
    }

    void OnDisable()
    {
        // Always unsubscribe. Otherwise the event keeps a reference to a destroyed object.
        SceneManager.sceneLoaded -= HandleSceneLoaded;
    }

    void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        Debug.Log("Loaded " + scene.name);
    }
}

Common Mistakes

See also