Menu
CoddyTech

UnityEvent 字段

本课属于 Coddy Unity 学习旅程的“Unity 游戏架构”单元。第 14 课,共 64 课。

按钮的 On Click () 是一个 UnityEvent 字段,你自己的脚本也可以有这样的字段。公共 UnityEvent 字段会在 Inspector 中显示为同类列表,脚本通过 Invoke() 触发它,而无需知道它连接了什么。这个倒计时每秒计时一次:

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();
        }
    }
}

在 Inspector 中,On Finished () 可以添加类似按钮的条目:一个条目发射火箭,另一个打开大门。另一个关卡可以用其他条目重复使用同一个 Countdown,无需任何人编写新脚本。UnityEvent<int> 会传递一个值。在它的下拉菜单中,接受 int 的方法会列在 Dynamic int 下,该条目会获取传给 Invoke 的值,也就是这里剩余的秒数。同一个方法也可以列在 Static Parameters 下,这种情况下,条目会使用手动输入的数字;不带参数的方法也可以连接。

Unity 会在加载脚本时创建 UnityEvent 字段,因此 onTick 永远不会是 null,不需要 ?.,代码还可以通过 onTick.AddListener(ShowSeconds) 添加监听器。如果不同对象的响应不同,而且由你或从不开启脚本的设计师在 Inspector 中设置,就选择 UnityEvent。如果由代码监听,就选择 C# 事件:编译器会检查方法名,因此重命名会导致构建失败,而不是留下一个无提示的 <Missing> 条目;C# 事件也不会显示在 Inspector 中。

challenge icon

挑战

简单

为 FinishLine 添加场景中各行所连接的事件。

  1. 添加 using UnityEngine.Events;、public UnityEvent<int> onLap;、public UnityEvent onRaceOver;,以及一个用于记录已完成圈数的私有 int 变量。
  2. 在 OnTriggerEnter 中,当 other 带有 Player 标签时,记录圈数,并将已完成的圈数传给 onLap.Invoke。
  3. 圈数达到 laps 时,调用 onRaceOver.Invoke();之后再穿过终点线不会有任何效果。

按下 Play,驾驶车辆完成三圈,然后点击 Check。

亲手试试

using UnityEngine;

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

    void OnTriggerEnter(Collider other)
    {
        // 赛车越过终点线:又完成了一圈
    }
}

Unity 游戏架构中的所有课

自己练习: Unity 在线编辑器