文档

Unity Engine

Unity Engine

检视面板可配置的自定义事件

Create your own custom events to configure persistent (lasting between Edit mode and Play mode) callbacks in the Inspector window.
阅读时间5 分钟最后更新于 1 个月前

Unity 提供了 UnityEvent API 作为标准 C# 事件和委托的 Unity 特定替代方案。相比于标准 C# 事件,Unity 事件的主要优点在于 Unity 事件可序列化,这意味着可以在检视面板 (Inspector) 窗口中配置它们。
UnityEvent
可以添加至任何
MonoBehaviour
,并在运行时像标准 C# 委托一样执行。在
MonoBehaviour
中声明
UnityEvent
时,它会显示在检视面板窗口中,您可以在其中定义在编辑时间和运行时之间持续存在的回调。
Unity 事件具有与标准 C# 委托类似的限制:
  • 它们会保留对目标对象的引用,而这会阻止对目标对象进行垃圾收集。
  • 如果目标为托管 (C#)
    UnityEngine.Object
    ,并且已销毁非托管 (C++) 对应对象,则不会调用回调。请参阅 Null 引用以了解更多上下文信息。

配置 Unity 事件

先决条件

  • 创建包含
    using UnityEngine.Events
    的 MonoBehaviour 脚本
  • 声明至少一个
    UnityEvent
    类型的字段

在检视面板窗口中配置回调:

  1. 选择包含脚本组件的游戏对象,该脚本组件包含您声明的
    UnityEvent
    字段。
  2. 单击事件名称下的 + 按钮可添加回调字段。
  3. 选择要接收回调的 UnityEngine.Object。可以使用对象选择器或将对象拖放到字段中。
  4. 选择要在事件发生时调用的函数。下拉选单中会填充游戏对象及其组件上可用的适当方法的过滤列表。
  5. 根据需要重复第 1-4 步,为同一事件添加其他回调。

在检视面板窗口中为名为 Trigger Entered 和 Trigger Exited 的事件配置回调

静态和动态调用

在检视面板窗口中配置
UnityEvent
时,支持两种类型的函数调用:
  • 静态调用在创作时完全预先配置,其目标和参数值在检视面板窗口中定义。调用回调时,将使用检视面板中定义的参数值调用目标函数。这适用于在运行时不会改变的值,例如,每次发生特定碰撞时,您都会希望角色健康值减少固定的值。静态绑定的函数显示在函数选择列表中的静态参数 (Static Parameters) 下方。
  • 动态调用以编程方式从代码中调用,参数与调用的
    UnityEvent
    类型相匹配。这适用于在运行时变化的值,例如,表示角色在每次受攻击时承受的变化伤害量的
    float
    。UI 会过滤回调,仅显示签名对
    UnityEvent
    类型有效的动态函数。例如,如果有
    UnityEvent<string>
    ,则函数选择器会在动态字符串 (Dynamic string) 标题下列出接受
    string
    参数的所有函数。

选择签名与检视面板窗口中的事件类型相匹配的静态或动态函数

UnityEvent 中的泛型支持

默认情况下,
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); } }}

其他资源