UnityEvent
TypeClass
NamespaceUnityEngine.Events
VariantsUnityEvent<T0> up to UnityEvent<T0, T1, T2, T3>
Seen inButton "On Click ()", Slider "On Value Changed"

UnityEvent

A UnityEvent is a list of methods to call when something happens. The special part is that you can fill that list in the Inspector by dragging objects and picking methods from a dropdown, the same way a UI Button's "On Click" works. You don't need code to connect them.

A doorbell. The button (your script) doesn't know or care what the bell is wired to. It could be a chime, a light, or a message to your phone. It just rings (Invoke()). Whoever installs it (you, in the Inspector) decides what's connected. This means you can reuse the same button in many places and connect it to different things each time.

Methods

MethodReturnsDescription
Invoke()voidCalls every connected method (Inspector ones first, then code ones). For UnityEvent<T>: Invoke(value).
AddListener(UnityAction call)voidConnect a method from code.
RemoveListener(UnityAction call)voidDisconnect a method added with AddListener.
RemoveAllListeners()voidRemoves all code-added listeners. Does not remove the ones set in the Inspector.
GetPersistentEventCount()intHow many listeners were set up in the Inspector.
PressurePlateonPressed.Invoke()onPressedUnityEvent1. Door.Open()2. Light: SetActive(true)3. AudioSource.Play()listeners set in the Inspector, called in orderhas no reference tothe door, light or audio
The plate only knows its own event. Which methods run is stored in the Inspector (dashed), so adding a fourth reaction never touches PressurePlate.cs.

What the Inspector can call

In the dropdown, Unity lists public methods and property setters of every component on the object you dragged in, as long as they take zero or one parameter of a simple type (int, float, string, bool, or a Unity Object type).

Code Samples

A reusable pressure plate

using UnityEngine;
using UnityEngine.Events;

public class PressurePlate : MonoBehaviour
{
    [SerializeField] private UnityEvent onPressed;
    [SerializeField] private UnityEvent onReleased;

    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player")) onPressed.Invoke();
    }

    void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Player")) onReleased.Invoke();
    }
}

In the Inspector, click + under "On Pressed", drag in a door, and choose Door &gt; Open(). Add another entry for a light: GameObject &gt; SetActive (bool) with the box ticked.

An event that passes a value

using UnityEngine;
using UnityEngine.Events;

public class Health : MonoBehaviour
{
    [SerializeField] private float maxHealth = 100f;
    public UnityEvent<float> onHealthChanged; // passes health as a 0-1 fraction
    public UnityEvent onDied;

    private float health;

    void Start()
    {
        health = maxHealth;
        onHealthChanged.Invoke(1f);
    }

    public void TakeDamage(float amount)
    {
        if (health <= 0f) return;
        health = Mathf.Max(health - amount, 0f);
        onHealthChanged.Invoke(health / maxHealth);
        if (health == 0f) onDied.Invoke();
    }
}

Now drag a UI Slider into "On Health Changed" and choose Dynamic float > value. The bar updates by itself.

Listening from code

using UnityEngine;

public class DeathCounter : MonoBehaviour
{
    [SerializeField] private Health health;
    private int deaths;

    void OnEnable()  { health.onDied.AddListener(HandleDied); }
    void OnDisable() { health.onDied.RemoveListener(HandleDied); }

    private void HandleDied()
    {
        deaths++;
        Debug.Log("Deaths: " + deaths);
    }
}

UnityEvent vs. C# event

UnityEventC# event Action
Connect in InspectorYesNo
SpeedSlower (fine for gameplay moments)Faster
Best forDesigner-facing hooks: doors, buttons, triggers, "on death"Code-to-code events, things fired very often
SafetyAnyone with access can call Invoke()Only the owning class can invoke

What happens at runtime

  1. The Inspector connections are saved with the scene/prefab as data (object reference + method name).
  2. The first time you call Invoke, Unity looks up those methods by name and caches them.
  3. Invoke then calls each listener in order, one after another, on the same frame.
  4. If a listener's object was destroyed, Unity skips it for Inspector connections. Code listeners on destroyed objects can throw errors, which is why you remove them in OnDisable.

Common Mistakes

See also