Course contentsShow
← Unity Game Development
Lesson 275 of 8284. Prefabs and Data ManagementFree lesson

Handling Event Execution Order

Develop strategies to manage the order of operations when multiple listeners respond to the same event simultaneously within a frame.

In this lesson, you will learn how to gain deterministic control over which systems respond first when multiple listeners react to the same event.

When you use the Observer pattern with ScriptableObject Event Channels, many objects often listen for the same signal. By default, Unity does not guarantee the order in which these objects execute their response methods. If a "ScoreManager" and a "UIUpdater" both listen for a GameWon event, you might run into bugs if the UI tries to display a score before the Manager has finished calculating it.

To solve this, we avoid relying on implicit execution order. Instead, we use two primary strategies:

1. The Priority Queue Pattern

Instead of firing an event and hoping for the best, you can assign a priority level to your listeners. Modify your listener component to include a priority integer. When the event channel fires, sort your list of registered listeners based on this priority before invoking their callbacks.

2. Script Execution Order

For simpler systems, you can use Unity’s built-in Script Execution Order settings (found in Project Settings > Script Execution Order). By assigning your manager scripts a "Default Time" that is earlier or later than your UI scripts, you force Unity to call OnEnable and Awake at specific times. However, this is a "blunt instrument" that can become difficult to manage in large projects.

A cleaner approach is to decouple logic by using a "Controller" script that orchestrates the flow. Instead of multiple objects listening to the event directly, have a single EventManager listen to the event, perform the necessary logic in a strict sequence, and then notify the other systems manually:

public void OnEventRaised() 
{
    // Step 1: Data processing must happen first
    scoreManager.FinalizeScore();
    
    // Step 2: UI update happens after data is safe
    uiController.UpdateDisplay();
}

By centralizing the execution sequence, you eliminate race conditions where one script inadvertently reads stale data because another script hasn't finished its calculation yet.

Key Takeaway: Never assume the order of execution; either architect a central controller to sequence your responses or implement a priority system to force a predictable flow of data.