Menu
CoddyTech

UnityEvent Fields

Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 12 of 50.

A Button's On Click () is a UnityEvent field, and your own scripts can have one too. A public UnityEvent field shows in the Inspector as the same kind of list, and the script raises it with Invoke() without knowing what is wired to it. This countdown ticks once a second:

using UnityEngine;
using UnityEngine.Events;

public class Countdown : MonoBehaviour
{
    public int seconds = 3;
    public UnityEvent<int> onTick;
    public UnityEvent onFinished;

    void Start()
    {
        InvokeRepeating("Tick", 1f, 1f);
    }

    void Tick()
    {
        seconds--;
        onTick.Invoke(seconds);
        if (seconds == 0)
        {
            CancelInvoke("Tick");
            onFinished.Invoke();
        }
    }
}

In the Inspector, On Finished () takes rows like a button's: one row launches the rocket, another opens the gate. Another level reuses the same Countdown with other rows, and nobody writes a new script. UnityEvent<int> passes a value. In its dropdown a method that takes an int is listed under Dynamic int, and that row gets the value given to Invoke, here the seconds left. The same method under Static Parameters gets a number typed into the row instead, and methods with no parameter can be wired as well.

Unity creates a UnityEvent field when it loads the script, so onTick is never null and needs no ?., and code can add listeners with onTick.AddListener(ShowSeconds). Choose a UnityEvent when the reaction differs from object to object and is set up in the Inspector, by you or by a designer who never opens the script. Choose a C# event when code listens: the compiler checks the method names, so a rename breaks the build instead of leaving a quiet <Missing> row, and a C# event never shows in the Inspector.

challenge icon

Challenge

Easy

A three-lap race around the island. The arrows drive the car (Car.cs), and the scene is wired the way a designer would wire it in the Inspector: the FinishLine's On Lap (Int32) list calls LapBoard.ShowLaps (Dynamic int) on the LapText and Crowd.Cheer on the Crowd, and its On Race Over () list calls LapBoard.ShowFinished and Car.Stop. Those scripts are ready, but the rows have nothing to attach to until FinishLine has the events.

Write FinishLine.cs:

  • Two UnityEvent fields: onLap, which passes an int, and onRaceOver, which passes nothing.
  • Each time the car (tagged Player) enters the line, a lap is done: invoke onLap with the number of laps done (1, then 2, then 3). Nothing else that crosses the line counts.
  • When the laps done reach laps (3), invoke onRaceOver. After that, crossing the line does nothing.

Press Play, drive three laps around the island, then Check.

Try it yourself

using UnityEngine;

public class FinishLine : MonoBehaviour
{
    public int laps = 3;

    void OnTriggerEnter(Collider other)
    {
        // the car crossed the line: one more lap done
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Game Architecture in Unity