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 中。
挑战
简单为 FinishLine 添加场景中各行所连接的事件。
- 添加
using UnityEngine.Events;、public UnityEvent<int> onLap;、public UnityEvent onRaceOver;,以及一个用于记录已完成圈数的私有 int 变量。 - 在
OnTriggerEnter中,当other带有Player标签时,记录圈数,并将已完成的圈数传给onLap.Invoke。 - 圈数达到
laps时,调用onRaceOver.Invoke();之后再穿过终点线不会有任何效果。
按下 Play,驾驶车辆完成三圈,然后点击 Check。
亲手试试
using UnityEngine;
public class FinishLine : MonoBehaviour
{
public int laps = 3;
void OnTriggerEnter(Collider other)
{
// 赛车越过终点线:又完成了一圈
}
}
Unity 游戏架构中的所有课
自己练习: Unity 在线编辑器