Unity 提供了 UnityEvent API 作为标准 C# 事件和委托的 Unity 特定替代方案。相比于标准 C# 事件,Unity 事件的主要优点在于 Unity 事件可序列化,这意味着可以在检视面板 (Inspector) 窗口中配置它们。
UnityEvent 可以添加至任何 MonoBehaviour,并在运行时像标准 C# 委托一样执行。在 MonoBehaviour 中声明 UnityEvent 时,它会显示在检视面板窗口中,您可以在其中定义在编辑时间和运行时之间持续存在的回调。
Unity 事件具有与标准 C# 委托类似的限制:
UnityEngine.Object,并且已销毁非托管 (C++) 对应对象,则不会调用回调。请参阅 Null 引用以了解更多上下文信息。using UnityEngine.Events 的 MonoBehaviour 脚本UnityEvent 类型的字段选择包含脚本组件的游戏对象,该脚本组件包含您声明的 UnityEvent 字段。
单击事件名称下的 + 按钮可添加回调字段。
选择要接收回调的 UnityEngine.Object。可以使用对象选择器或将对象拖放到字段中。
选择要在事件发生时调用的函数。下拉选单中会填充游戏对象及其组件上可用的适当方法的过滤列表。
根据需要重复第 1–4 步,为同一事件添加其他回调。
在检视面板窗口中配置 UnityEvent 时,支持两种类型的函数调用:
UnityEvent 类型相匹配。这适用于在运行时变化的值,例如,表示角色在每次受攻击时承受的变化伤害量的 float。UI 会过滤回调,仅显示签名对 UnityEvent 类型有效的动态函数。例如,如果有 UnityEvent<string>,则函数选择器会在动态字符串 (Dynamic string) 标题下列出接受 string 参数的所有函数。
默认情况下,Monobehaviour 中的 UnityEvent 动态绑定到 void 函数。但是,可以创建一个最多包含四个泛型类型参数的 UnityEvent,如下例所示:
using UnityEngine;
using UnityEngine.Events;
public class GenericTest : MonoBehaviour
{
public UnityEvent<int, int, bool, string> myEvent;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
if (myEvent == null)
{
myEvent = new UnityEvent<int, int, bool, string>();
}
myEvent.AddListener(Ping);
}
// Update is called once per frame
void Update()
{
if (Input.anyKeyDown && myEvent != null)
{
myEvent.Invoke(5, 6, true, "Hello");
}
}
void Ping(int i, int j, bool print, string text)
{
if (print)
{
Debug.Log("Ping: " + text + i + j);
}
}
}