Events and Delegates In Unity

Last Updated : 4 May, 2026

A delegate is a variable that holds a reference to a method. An event uses delegates to notify multiple scripts when something happens.

  • One script announces an event
  • Other scripts listen and respond
  • The sender doesn't need to know the receivers

Events and delegates in Unity are used to enable communication between different scripts in a flexible and decoupled way. 

Need of Events

Without events:

C#
void OnCoinPickup()
{
    scoreManager.AddScore(10);
    audioManager.PlayCoinSound();
    uiManager.UpdateScore();
}

With events:

C#
void OnCoinPickup()
{
    OnCoinCollected?.Invoke();  // Anyone listening will respond
}

The coin doesn't need to know who is listening. You can add or remove listeners without changing the coin script.

Creating an Event

This script fires an event when player touches the coin. Any script listening will respond.

C#
public class Coin : MonoBehaviour
{
    public delegate void CoinCollected();
    public static event CoinCollected OnCoinCollected;
    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            OnCoinCollected?.Invoke();
            Destroy(gameObject);
        }
    }
}

OnCoinCollected?.Invoke() calls all listening methods. The ? checks if any listeners exist.

Listening to Events

This script subscribes to the coin event and adds score when coin is collected.

C#
public class ScoreManager : MonoBehaviour
{
    void OnEnable()
    {
        Coin.OnCoinCollected += AddScore;
    }
    void OnDisable()
    {
        Coin.OnCoinCollected -= AddScore;
    }
    void AddScore()
    {
        Debug.Log("Score +10");
    }
}

+= subscribes to event. -= unsubscribes - important to prevent memory leaks.

Passing Data with Events

Sometimes you need to pass data like score value or damage amount.

Example: Enemy

C#
public class Enemy : MonoBehaviour
{
    public delegate void EnemyDied(int scoreValue);
    public static event EnemyDied OnEnemyDied;
    void Die()
    {
        OnEnemyDied?.Invoke(50);  // Pass 50 points
        Destroy(gameObject);
    }
}

ScoreManager:

C#
public class ScoreManager : MonoBehaviour
{
    void OnEnable()
    {
        Enemy.OnEnemyDied += AddScore;
    }
    void OnDisable()
    {
        Enemy.OnEnemyDied -= AddScore;
    }
    void AddScore(int points)
    {
        score += points;
    }
}

Complete Example: Health Events

Health script fires events when health changes or player dies.

Example: Health

C#
public class Health : MonoBehaviour
{
    public int currentHealth = 100;
    public delegate void HealthChanged(int current, int max);
    public static event HealthChanged OnHealthChanged;
    public delegate void PlayerDied();
    public static event PlayerDied OnPlayerDied;
    public void TakeDamage(int amount)
    {
        currentHealth -= amount;
        OnHealthChanged?.Invoke(currentHealth, 100);
        
        if (currentHealth <= 0)
        {
            OnPlayerDied?.Invoke();
        }
    }
}

UI script listens and updates health bar.

C#
public class HealthBar : MonoBehaviour
{
    public Slider healthSlider;
    void OnEnable()
    {
        Health.OnHealthChanged += UpdateHealthBar;
        Health.OnPlayerDied += ShowGameOver;
    }
    void OnDisable()
    {
        Health.OnHealthChanged -= UpdateHealthBar;
        Health.OnPlayerDied -= ShowGameOver;
    }
    void UpdateHealthBar(int current, int max)
    {
        healthSlider.value = (float)current / max;
    }
    void ShowGameOver()
    {
        Debug.Log("Game Over");
    }
}

UnityEvent

UnityEvent can be assigned in Inspector without writing code.

C#
using UnityEngine.Events;
public class ButtonTrigger : MonoBehaviour
{
    public UnityEvent OnButtonPressed;
    void OnTriggerEnter(Collider other)
    {
        OnButtonPressed.Invoke();
    }
}

In Inspector, you can drag GameObjects and select methods to call.

Comment
Article Tags:

Explore