Course contentsShow
← Unity Game Development
Lesson 330 of 8285. UI and Audio SystemsFree lesson

Handling UI Events Across Multiple Scenes

Learners will develop a persistent event bus architecture to maintain UI state and event listeners when transitioning between different game scenes.

In this lesson, you will learn how to use a persistent Event Bus to communicate UI updates across different scenes without losing your event connections.

The Challenge of Scene Transitions

When you switch scenes in Unity, all objects in the current scene are destroyed. If your UI components are "listening" to a specific object or manager in that scene, those connections break the moment the new scene loads. To keep your UI reactive—like updating a player's gold count or health bar regardless of which level they are in—you need an Event Bus.

The Persistent Event Bus Architecture

An Event Bus is a central "message board" that exists independently of your scenes. By creating a ScriptableObject to act as this bus, it stays in memory even when the scene changes.

Here is how you structure a simple event channel:

[CreateAssetMenu]
public class UIEventChannel : ScriptableObject
{
    // A delegate for other scripts to subscribe to
    public System.Action<int> OnCurrencyChanged;

    public void RaiseCurrencyChanged(int newAmount)
    {
        OnCurrencyChanged?.Invoke(newAmount);
    }
}

Implementing the Pattern

  1. The Sender: When an action occurs (e.g., collecting a coin), you reference the UIEventChannel asset and call RaiseCurrencyChanged(100). Because the channel is a global asset, it doesn't matter what scene the script is in.
  2. The Listener: Your UI components (like a GoldDisplay script) subscribe to the event in OnEnable and unsubscribe in OnDisable:
public class GoldDisplay : MonoBehaviour
{
    public UIEventChannel channel;

    private void OnEnable() => channel.OnCurrencyChanged += UpdateUI;
    private void OnDisable() => channel.OnCurrencyChanged -= UpdateUI;

    private void UpdateUI(int amount) => myLabel.text = amount.ToString();
}

By decoupling the UI from specific scene objects and routing everything through this shared ScriptableObject channel, your UI remains perfectly synchronized across your entire game. Your components no longer care who sent the event, only that they are tuned into the right channel.

Key Takeaway: Use persistent ScriptableObject-based event channels to decouple your UI from scene-specific objects, ensuring event listeners stay active during scene transitions.