In this lesson, you will learn how to use C# Action delegates to create a decoupled communication bridge between your game systems, allowing objects to react to state changes without needing direct references to one another.
Moving Beyond Direct Coupling
In many projects, you might be tempted to let a PlayerController talk directly to a UIManager (e.g., uiManager.UpdateHealth(currentHealth)). While simple, this creates "spaghetti code" where the Player must know about the UI to function. If you delete the UI, your code breaks.
The Observer Pattern solves this by letting the Player "broadcast" that something happened without caring who—if anyone—is listening. This is achieved using C# Action delegates.
Implementing the Event Channel
Instead of calling a method directly, the subject defines an event. Other systems subscribe to this event when they are active.
using System;
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
// Define an action that takes an integer
public static event Action<int> OnHealthChanged;
public void TakeDamage(int amount)
{
// Broadcast the change to anyone listening
OnHealthChanged?.Invoke(currentHealth - amount);
}
}
Now, your HealthBarUI component can simply listen to this channel without the Player knowing it exists:
public class HealthBarUI : MonoBehaviour
{
private void OnEnable() => PlayerHealth.OnHealthChanged += UpdateUI;
private void OnDisable() => PlayerHealth.OnHealthChanged -= UpdateUI;
private void UpdateUI(int newHealth)
{
// Update the slider logic here
}
}
Why This Matters
By using Action, we achieve perfect decoupling. You can have a sound manager, a screen-shake script, and a UI manager all react to OnHealthChanged simultaneously. If you want to remove the screen-shake later, you simply delete that script; you never have to touch the PlayerHealth code. This adheres strictly to the Open-Closed Principle, as you can add new reactive behaviors without ever modifying your core game logic.
Key Takeaway: Use C# Actions to broadcast game state changes as events, allowing decoupled systems to react independently without requiring direct object references.