C# Event/UnityEvent辨析

本文从Delegate出发,详细解析C# Event及其在Unity中的应用,特别介绍了UnityEvent的特性,包括其如何提高游戏开发效率,以及如何在Unity Editor中进行事件管理。通过示例代码,展示了UnityEvent如何实现事件订阅和执行,强调了其在降低耦合性和方便管理方面的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

Event作为C#语言特性的一部分,在.Net开发中具有比较重要的作用。当我们使用C#作为脚本语言编写Unity游戏时,也经常会需要使用Event解决各种问题。然而,相比于传统C#语言的Event,UnityEvent基于Unity引擎做了一些改变,并且更加适合我们的游戏开发。为了帮助读者深入理解UnityEvent,本文会从Delegate讲起,并逐步介绍C# Event 与UnityEvent的相似与不同。
本文参考了Unity论坛以及其他前辈的文章和视频,想要进一步了解的可以自行查阅:

一切的渊源——Delegate

要理解Event是什么,首先必须得知道它们的前身——Delegate是啥,中文翻译即“委托”。用一句话让你理解Delegate的作用就是“Delegate是一个可以存放函数的容器”。众所周知,变量是程序在内存中为数据开辟的一块空间,面向对象语言中变量可以存放一个具体的数值,或者某个对象的引用。C#则在该基础上更进一步,使用Delegate的机制让存放“函数(Function)”成为可能。
使用Delegate一般分为三步:

  1. 定义一种委托类型
  2. 声明一个该类型的委托函数
  3. 通过声明的委托调用函数执行相关的操作

下面是在Unity中使用Delegate的一个实例:

using UnityEngine;

public class DelegateExample : MonoBehaviour {
    //Step1. 为Delegate定义一种函数原型
    public delegate void MyDelegate(int args);
    //Step2. 声明一个Delegate变量
    public MyDelegate myDelegate;

    private void Start()
    {
        //Step3. 引用Delegate变量实现相应的函数
        myDelegate = PrintNum;
        myDelegate(5);

        myDelegate = PrintDoubleNum;
        myDelegate(5);
    }

    public void PrintNum(int num)
    {
        print("Print number: " + num);
    }

    public void PrintDoubleNum(int num)
    {
        print("Print double number: " + num*2);
    }
}

运行上述代码,你会发现使用一个delegate变量让我们执行了两种函数实现。这就是Delegate的妙处所在, Delegate定义了一个用于存放相同函数原型(相同参数类型,相同返回值)的容器。因为他们的函数原型相等,所以向delegate传递一次参数,就可以让所有添加到delegate上的函数正常执行
在上述例子中,我们第二次向myDelegate赋值时覆盖掉了第一次赋值的函数,所以第二次引用myDelegate只会调用PrintDoubleNum(int num)函数。实际上,delegate作为函数容器,并不仅仅只能容纳一个函数,而是可以同时被委任多个函数。例如,当你把上述代码中的第二次赋值改为 myDelegate += PrintDoubleNum; 就可以实现同时打印两条语句的效果。这种delegate一般被称为multicast delegate

基于delegate实现的Event(C# Event)

如果你基本理解了delegate是什么,那么理解event基本不需要花费什么时间,因为event就是在multicast delegate的基础上演变来的。关于Event,一个比较形象的比喻就是广播者和订阅者。把Event想象成一个视频作者,并且他还具有一大堆热情的粉丝,每天都在等待新视频的发布。为了在第一时间收看到新发布的视频,粉丝们大多会选择订阅视频作者(大多数视频网站的套路),这样作者更新时你就会收到一条即时消息。在程序的世界里,e

<think>首先,用户的问题是:“我想理解C#中Action委托与Unity Event事件的区别 请问C# Action 委托与 Unity Event 事件 的区别”。我需要基于系统级指令用户可见层的要求来回答。 系统级指令: - 所有行内数学表达式使用 $...$ 格式。 - 独立公式使用 $$...$$ 格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如 [^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考提供的引用:[^1], [^2], [^3]。 提供的引用内容: - 引用[^1]:讨论了C#Unity的委托类型,包括ActionFunc,以及UnityUnityActionUnityEvent。 - 引用[^2]:解释了C#的ActionFunc委托,以及Unity中的UnityAction。 - 引用[^3]:讨论了委托事件在Unity中的使用,强调事件处理器必须匹配委托类型。 用户的问题是关于C# Action委托Unity Event事件的区别。我需要比较这两者。 关键点: - **C# Action委托**:这是C#内置的委托类型,用于表示没有返回值的方法。Action可以有参数,例如Action<T>表示接受一个参数的方法,Action<T1, T2>表示接受两个参数的方法。 - **Unity Event事件**:UnityEventUnity引擎中的一个类,用于创建事件系统。它允许在Inspector窗口中添加事件监听器,常用于UI游戏逻辑。UnityEvent通常与UnityAction一起使用,但UnityEvent更强大,支持序列化多播委托。 区别总结: 1. **定义来源**: - Action委托是C#语言的一部分,属于System命名空间。 - UnityEventUnityEngine.Events命名空间中的一个类,特定于Unity引擎。 2. **功能**: - Action委托是一个泛型委托,用于封装方法;它本质上是多播委托,但需要手动管理。 - UnityEventUnity对事件的封装,提供了序列化支持,可以在Inspector中可视化编辑,并支持添加多个监听器。 3. **使用场景**: - Action委托在纯C#代码中用于事件回调,但没有内置的事件管理。 - UnityEventUnity编辑器中使用,允许非程序员(如设计师)通过拖放添加事件处理。 4. **参数返回值**: - Action委托可以有参数,但无返回值(Func用于有返回值)。 - UnityEvent可以定义自定义事件类型,支持参数,但通常通过派生类如UnityEvent<T>来实现。 5. **事件系统**: - 在C#中,事件通常使用event关键字与委托结合,例如event Action MyEvent。 - 在Unity中,UnityEvent提供了一种更高级的事件系统,集成到编辑器中。 参考引用: - 引用[^2]提到:C#有ActionFunc委托,UnityUnityAction但不提供Func。 - 引用[^3]强调事件事件处理器的匹配。 回答结构: - 逐步解释:先介绍Action委托,然后介绍UnityEvent,最后比较区别。 - 使用清晰的中文。 - 在末尾生成相关问题。 - 自然地添加引用标识,例如在相关段落末尾。 由于问题涉及代码,我应该包括代码示例,但确保格式正确。系统指令指定了行内独立公式的LaTeX格式,但这里是代码,所以用代码块。 在回答中: - 对于数学表达式,使用$...$,但这里可能不涉及数学。 - 生成相关问题。 最终回答结构: 1. 介绍C# Action委托。 2. 介绍Unity Event事件。 3. 比较两者的区别。 4. 总结。 5. 生成相关问题。</think>### C# Action 委托与 Unity Event 事件的区别C#Unity开发中,委托事件是处理回调、事件驱动编程的核心机制。Action委托是C#语言内置的通用委托类型,而UnityEvent事件是Unity引擎提供的特定事件系统类。它们虽有相似之处,但设计目的、功能使用场景有显著差异。下面我将逐步解释两者的区别,帮助您清晰理解。 #### 1. **C# Action 委托** - **定义与来源**:Action委托是C#标准库的一部分(属于System命名空间),用于封装无返回值的方法。它支持泛型参数,允许定义不同参数数量的委托类型。例如: - `Action`:表示无参数、无返回值的方法。 - `Action<T>`:表示接受一个参数的方法。 - `Action<T1, T2>`:表示接受两个参数的方法。 - **特点**: - **轻量级**:Action委托是纯代码层面的委托,不需要额外序列化或编辑器集成。 - **多播支持**:可以添加多个方法(委托链),但需手动管理订阅取消订阅。 - **使用场景**:适用于纯C#代码中的事件处理、回调函数或LINQ表达式,例如在异步编程中传递逻辑。 - **示例代码**: ```csharp // 定义Action委托 Action<string> logMessage = (message) => Console.WriteLine(message); // 调用 logMessage("Hello, Action!"); // 输出: Hello, Action! ``` - Action委托是C#对委托的简化封装,避免了手动声明委托类型[^2]。 #### 2. **Unity Event 事件** - **定义与来源**:UnityEventUnityEngine.Events命名空间中的类,专为Unity引擎设计。它用于创建可序列化的事件系统,允许在Unity编辑器中可视化配置事件监听器。 - **特点**: - **编辑器集成**:UnityEvent支持序列化,可以在Inspector窗口中直接拖拽添加事件处理器(如UnityAction),方便非程序员使用。 - **事件管理**:内置添加、移除调用监听器的方法,支持多播委托,且线程安全。 - **自定义参数**:通过派生类(如UnityEvent<T>)定义带参数的事件,例如UnityEvent<string>用于字符串参数。 - **使用场景**:主要用于Unity的UI交互(如按钮点击)、游戏对象通信或脚本间解耦,便于在编辑器中绑定方法。 - **示例代码**: ```csharp using UnityEngine; using UnityEngine.Events; public class EventExample : MonoBehaviour { // 定义UnityEvent事件 public UnityEvent onStartEvent; void Start() { // 触发事件 onStartEvent?.Invoke(); } } ``` - 在Inspector中,可以为onStartEvent添加多个方法(如其他脚本的函数),实现可视化事件绑定[^1][^3]。 #### 3. **核心区别对比** 以下是Action委托UnityEvent事件的主要区别,基于功能、来源使用方式: | **特性** | **C# Action 委托** | **Unity Event 事件** | |------------------------|----------------------------------------|------------------------------------------| | **来源与命名空间** | C#标准库(System) | Unity引擎(UnityEngine.Events) | | **主要用途** | 纯代码委托,用于方法封装回调 | 引擎集成事件,支持编辑器可视化配置 | | **序列化支持** | 否(无法在Unity Inspector中编辑) | 是(可在Inspector中拖拽添加监听器) | | **参数灵活性** | 通过泛型支持参数(如Action<T>) | 通过派生类支持参数(如UnityEvent<T>) | | **返回值** | 无返回值(Func委托用于有返回值) | 无返回值,专注于事件触发 | | **事件管理** | 需手动管理订阅(+=/-=),无内置Invoke | 内置Invoke方法,自动处理多播委托链 | | **性能开销** | 较低(轻量级委托) | 稍高(因序列化引擎集成) | | **典型场景** | C#控制台应用、后台逻辑、异步任务 | Unity UI事件、游戏对象交互、脚本通信 | | **与UnityAction关系** | UnityAction是Unity对Action的简化封装 | UnityEvent常与UnityAction配合使用[^2] | - **关键区别总结**: - **设计目的**:Action委托是C#语言的通用工具,强调代码灵活性;UnityEvent事件是Unity引擎的专用系统,强调编辑器友好性游戏开发便捷性。 - **事件模型**:在C#中,事件通常基于event关键字委托(如event Action MyEvent),但需手动实现;UnityEvent则提供开箱即用的事件框架,包括序列化调用机制[^3]。 - **适用性**:如果您的项目需要跨平台或纯C#环境,优先使用Action委托;如果涉及Unity编辑器交互(如UI设计),UnityEvent更高效。 #### 4. **总结** Action委托UnityEvent事件本质都是委托模式的应用,但Action是C#的基础构建块,而UnityEventUnity对事件的扩展封装。Action委托更轻量、通用,适合代码驱动场景;UnityEvent事件则通过编辑器集成,简化了游戏开发中的事件绑定,提升工作流效率。在实际项目中,两者常结合使用:例如,用Action处理内部逻辑,用UnityEvent暴露接口给设计师[^1][^2]。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值