Version: 6000.3
语言: 中文
事件函数
使用更新管理器优化每帧更新

检查器可配置的自定义事件

Unity 提供 UnityEvent API 作为标准 C# 事件和委托的特定于 Unity 的替代方案。与标准 C# 事件相比,Unity 事件的主要优势在于 Unity 事件是可序列化的,这意味着您可以在 Inspector 窗口中配置它们。

一个UnityEvent可以添加到任何MonoBehaviour并在运行时像标准 C# 委托一样执行。当UnityEventMonoBehaviour它出现在检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
请参阅术语表
窗口,您可以在其中定义在编辑时间和运行时之间保留的回调。

Unity 事件与标准 C# 委托具有类似的限制:

  • 它们保存对目标对象的引用,这会阻止目标对象被垃圾回收。
  • 如果你有一个托管 (C#)UnityEngine.Object由于目标和非托管 (C++) 对应对象已被销毁,因此不会调用回调。有关更多信息,请参阅对象Unity 场景中的基本对象,可以表示角色、道具、风景、相机、航路点等。游戏对象的功能由附加到它的组件定义。更多信息
    请参阅术语表
    .

配置 Unity 事件

先决条件

  • 创建一个 MonoBehaviour 脚本,其中包括using UnityEngine.Events
  • 声明至少一个类型为UnityEvent

在 Inspector 窗口中配置回调:

  1. 选择包含包含声明的UnityEvent字段。

  2. 点击事件名称下方的 + 按钮,为回传添加槽位。

  3. 选择要接收回调的 UnityEngine.Object。您可以使用对象选择器或将对象拖放到字段中。

  4. 选择要在事件发生时调用的函数。下拉选择器填充了游戏对象及其组件上可用的适当方法的筛选列表。

  5. 根据需要重复步骤 1-4,为同一事件添加其他回传。

在“检查器”窗口中为名为“已进入触发器”和“已退出触发器”的事件配置回调
在“检查器”窗口中为名为“已进入触发器”和“已退出触发器”的事件配置回调

静态和动态调用

配置UnityEvent“检查器”窗口中,支持两种类型的函数调用:

  • 静态调用在创作时完全预先配置,其目标值和参数值在“检查器”窗口中定义。调用回调时,将使用检查器中定义的参数值调用目标函数。这适用于在运行时不会变化的值,例如,当你想在每次特定碰撞当物理引擎检测到两个游戏对象的碰撞器接触或重叠时,当至少一个游戏对象具有刚体组件并且处于运动状态时,就会发生碰撞。更多信息
    请参阅术语表
    发生。静态绑定的函数显示在函数选择列表中的 静态参数(Static Parameters) 下。
  • 动态调用以编程方式从代码中调用,参数与UnityEvent被调用。这适用于在运行时变化的值,例如float代表角色在每次攻击中承受的可变伤害量。UI 会过滤回调,并仅显示具有对UnityEvent.例如,如果您有UnityEvent<string>,函数选择器列出任何接受string参数。
在签名与“检查器”窗口中的事件类型匹配的静态或动态函数之间进行选择
在签名与“检查器”窗口中的事件类型匹配的静态或动态函数之间进行选择

UnityEvent 中的通用支持

默认情况下,一个UnityEventMonobehaviour动态绑定到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);
        }
    }
}

其他资源

事件函数
使用更新管理器优化每帧更新