Unity Function Execution Order

Learn about Unity's lifecycle function execution order. Understand when functions like Awake, Start, and Update are executed.

Unity executes functions in a specific order according to the script's lifecycle. Understanding this order is crucial in Unity development.

Main Function Execution Order

1. Awake()          - When object is created (once only)
2. OnEnable()       - When object is enabled
3. Start()          - Before first frame (once only)
4. FixedUpdate()    - Physics update (fixed interval)
5. Update()         - Every frame
6. LateUpdate()     - After all Update()
7. OnGUI()          - GUI rendering
8. OnDisable()      - When object is disabled
9. OnDestroy()      - When object is destroyed

Detailed Explanation

Awake()

void Awake()
{
    // Executes first when object is created
    // Used to initialize references to other objects
    // All Awake() functions execute before Start() when Scene loads
    Debug.Log("Awake executed");
}

Characteristics:

  • All objects' Awake() functions execute first when Scene loads
  • Used to initialize references to other objects
  • Executes before Start()

OnEnable()

void OnEnable()
{
    // Executes every time object is enabled
    // When GameObject or script is enabled
    Debug.Log("OnEnable executed");
}

Characteristics:

  • Executes every time GameObject or script is enabled
  • Executes after Awake(), before Start()
  • Can execute multiple times

Start()

void Start()
{
    // Executes after Awake(), before first Update()
    // Used to initialize after all other objects are ready
    // Executes only once
    Debug.Log("Start executed");
}

Characteristics:

  • Executes after all Awake() functions have executed
  • Executes before first frame
  • Executes only once
  • Used after other objects' initialization is complete

FixedUpdate()

void FixedUpdate()
{
    // Executes at fixed time intervals (default 0.02 seconds)
    // Used for physics calculations (Rigidbody, etc.)
    // Uses Time.fixedDeltaTime
}

Characteristics:

  • Executes at fixed time intervals (default 0.02 seconds = 50Hz)
  • Time interval can be adjusted with Time.fixedDeltaTime
  • Used for physics calculations (Rigidbody, Collider, etc.)
  • Executes at constant intervals regardless of framerate

Update()

void Update()
{
    // Executes every frame (varies with framerate)
    // Used for input handling, game logic, etc.
    // Uses Time.deltaTime
}

Characteristics:

  • Executes every frame
  • Execution count varies with framerate
  • Used for input handling, game logic, etc.
  • Can use Time.deltaTime for frame-independent calculations

LateUpdate()

void LateUpdate()
{
    // Executes after all Update() functions
    // Used for camera tracking, etc.
}

Characteristics:

  • Executes after all Update() functions have executed
  • Used for camera tracking, UI updates, etc.
  • Useful when working after other objects' positions are finalized

OnGUI()

void OnGUI()
{
    // Function for GUI rendering
    // Can be called multiple times per frame
    // Only needed when using legacy GUI system
}

Characteristics:

  • Function for GUI rendering
  • Can be called multiple times per frame
  • Only needed when using legacy GUI system (IMGUI)
  • Not needed when using modern UI system (uGUI)

OnDisable()

void OnDisable()
{
    // Executes when object is disabled
    // When GameObject or script is disabled
    Debug.Log("OnDisable executed");
}

Characteristics:

  • Executes when GameObject or script is disabled
  • Can execute multiple times
  • Used for event unsubscription, etc.

OnDestroy()

void OnDestroy()
{
    // Executes when object is destroyed
    // When Scene ends or GameObject is Destroyed
    Debug.Log("OnDestroy executed");
}

Characteristics:

  • Executes when GameObject is destroyed
  • Also executes when Scene ends
  • Used for resource cleanup, event unsubscription, etc.

Execution Order Example

public class ExecutionOrderExample : MonoBehaviour
{
    void Awake()
    {
        Debug.Log("1. Awake");
    }
    
    void OnEnable()
    {
        Debug.Log("2. OnEnable");
    }
    
    void Start()
    {
        Debug.Log("3. Start");
    }
    
    void FixedUpdate()
    {
        Debug.Log("4. FixedUpdate");
    }
    
    void Update()
    {
        Debug.Log("5. Update");
    }
    
    void LateUpdate()
    {
        Debug.Log("6. LateUpdate");
    }
    
    void OnDisable()
    {
        Debug.Log("7. OnDisable");
    }
    
    void OnDestroy()
    {
        Debug.Log("8. OnDestroy");
    }
}

Execution Order Diagram

Scene Load
    ↓
[Awake] All objects' Awake() execute
    ↓
[OnEnable] Enabled objects' OnEnable() execute
    ↓
[Start] All objects' Start() execute
    ↓
┌─────────────────────────┐
│   Repeat every frame    │
│                         │
│  [FixedUpdate]          │
│  [Update]               │
│  [LateUpdate]           │
│  [OnGUI]                │
└─────────────────────────┘
    ↓
[OnDisable] When disabled
    ↓
[OnDestroy] When destroyed

Practical Usage Examples

Example 1: Ensuring Initialization Order

public class Manager : MonoBehaviour
{
    public static Manager Instance;
    
    void Awake()
    {
        // Initialize singleton (first)
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    void Start()
    {
        // Initialize after all other objects are ready
        InitializeGame();
    }
    
    void InitializeGame()
    {
        // Game initialization logic
    }
}

Example 2: Separating Physics and General Updates

public class PlayerController : MonoBehaviour
{
    private Rigidbody rb;
    private Vector3 input;
    
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
    
    void Update()
    {
        // Input handling (varies with framerate)
        input = new Vector3(
            Input.GetAxis("Horizontal"),
            0,
            Input.GetAxis("Vertical")
        );
    }
    
    void FixedUpdate()
    {
        // Physics movement (fixed time interval)
        rb.AddForce(input * 10f);
    }
}

Example 3: Camera Tracking

public class CameraFollow : MonoBehaviour
{
    public Transform target;
    private Vector3 offset;
    
    void Start()
    {
        offset = transform.position - target.position;
    }
    
    void LateUpdate()
    {
        // Update camera position after all Update() complete
        transform.position = target.position + offset;
    }
}

Notes

  1. Awake vs Start: Awake() executes before other objects initialize, Start() after all objects initialize
  2. Update vs FixedUpdate: General logic in Update(), physics calculations in FixedUpdate()
  3. OnEnable/OnDisable: Can execute multiple times, so be careful
  4. OnDestroy: Resource cleanup and event unsubscription are essential

Reference

Unity Official Documentation: Execution Order


← Back to Table of Contents