尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Unity里的delegate, event, Action, Func, UnityEvent, UnityAction和Event

Unity里的delegate, event, Action, Func, UnityEvent, UnityAction和Event
📅 发布时间:2026/7/12 17:19:09

C# / Unity 中 delegate、event、Action、Func、UnityEvent 的简单理解

背景

一直以来,我对各种“事件”的应用都有点迷迷糊糊。

平时写代码的时候,大多就是:

+=-=?.Invoke()

这样直接使用。

但是很多时候看源码,看到delegate、event、Action、Func、UnityEvent这些东西混在一起,就会有点懵。

所以这次专门花了一些时间翻文章、看代码,把自己的理解记录下来。


1. delegate

1.1 delegate 是什么?

delegate可以理解为一种类型安全的函数指针。

它的作用是:

用来存储一个或多个方法,并在需要的时候执行这些方法。

声明delegate的时候,本质上是在声明一个“委托类型”。

之后就可以用这个委托类型去声明变量,并让这个变量指向符合签名的方法。


1.2 delegate 的基本写法

publicdelegatevoidMyDelegate(intnumber);

这行代码的意思是:

声明一个名为MyDelegate的委托类型。

这个委托类型要求绑定的方法必须满足:

  • 无返回值:void
  • 有一个int类型参数

所以,后面只要方法符合这个签名,就可以赋值给MyDelegate类型的变量。


1.3 delegate 使用案例

usingUnityEngine;publicclassTest:MonoBehaviour{publicdelegatevoidMyDelegate(intnumber);privatevoidStart(){MyDelegatedel1=TestFunction1;del1(55);}privatevoidTestFunction1(intnum){Debug.Log("Test1: "+num);}}

这里的执行流程是:

MyDelegatedel1=TestFunction1;

表示把TestFunction1这个方法赋值给del1。

然后:

del1(55);

就相当于调用:

TestFunction1(55);

所以最终会输出:

Test1:55

2. event

2.1 event 是什么?

event是一个关键字。

从表现上看,它可以理解为一种受限制的 delegate。

它通常和委托类型一起使用。

例如:

publicdelegatevoidMyDelegate(intnumber);publiceventMyDelegatedel2;

这里的del2是一个事件。


2.2 event 和普通 delegate 的区别

在当前类内部,event修饰的委托变量,基本可以像普通委托一样使用:

del2=SomeFunction;del2+=SomeFunction;del2-=SomeFunction;del2?.Invoke(10);

但是在类的外部,event会限制访问权限。

外部类只能:

+=-=

不能直接:

=

也不能直接调用:

del2.Invoke();

2.3 为什么要用 event?

假如不用event,而是直接暴露一个 public delegate:

publicMyDelegatedel;

那么外部类可以直接这样写:

obj.del=null;

这样会把之前所有注册的方法都清空,风险很大。

而使用event后:

publiceventMyDelegatedel;

外部类就只能添加和移除监听:

obj.del+=SomeFunction;obj.del-=SomeFunction;

不能直接覆盖整个事件。

所以event的主要作用是:

保护委托变量,防止外部随意赋值、清空、调用。


2.4 event 的底层理解

可以简单理解为:

event会把委托变量的直接赋值权限限制起来。

外部访问时,只暴露类似下面这样的操作:

addremove

也就是外部的:

+=-=

本质上会走事件的添加和移除逻辑。

而=赋值和Invoke调用,只能在声明事件的类内部使用。


3. Action 和 Func

3.1 Action 和 Func 是什么?

Action和Func都是系统提前封装好的委托类型。

使用它们的好处是:

不需要自己手动声明 delegate,可以直接拿来用。


3.2 Action

Action表示没有返回值的委托。

例如系统内部大概是这样声明的:

namespaceSystem{publicdelegatevoidAction();}

也就是说:

ActionmyAction;

本质上就相当于声明了一个无参数、无返回值的委托变量。

如果需要参数,也可以写:

Action<int>action1;Action<int,string>action2;

3.3 Func

Func表示有返回值的委托。

例如:

namespaceSystem{publicdelegateTResultFunc<inT,outTResult>(Targ);}

常见写法:

Func<int,int>myFunc;

它表示:

  • 传入一个int
  • 返回一个int

最后一个泛型参数永远表示返回值类型。

例如:

Func<int,string,bool>func;

表示:

  • 第一个参数是int
  • 第二个参数是string
  • 返回值是bool

3.4 Action、Func 和 event 一起使用

Action和Func本身也是委托类型。

所以它们也可以配合event使用。

例如:

publicActionMyAction;publicFunc<int,int>MyFunc;publiceventActionMyActionEvent;

其中:

publicActionMyAction;

外部可以直接赋值、清空、调用。

而:

publiceventActionMyActionEvent;

外部只能+=和-=,不能直接赋值或调用。


3.5 代码案例

usingSystem;usingUnityEngine;publicclassTestDelegate:MonoBehaviour{publicActionMyAction;publicFunc<int,int>MyFunc;publiceventActionMyActionEvent;voidStart(){MyAction+=Test3;MyAction+=Test4;MyAction();MyAction=null;Debug.Log("**************");MyFunc=Test5;intresult=MyFunc(77);Debug.Log("Result: "+result);MyFunc=null;Debug.Log("**************");MyActionEvent=Test3;MyActionEvent();MyActionEvent=null;}publicvoidTest3(){Debug.Log("Test3");}publicvoidTest4(){Debug.Log("Test4");}publicintTest5(intnum){Debug.Log("Test5: "+num);returnnum;}}

在当前类TestDelegate内部:

MyActionEvent=Test3;MyActionEvent();MyActionEvent=null;

这些都是合法的。

但是如果在外部类中这样写:

publicclassTest:MonoBehaviour{publicTestDelegatet;privatevoidStart(){t.MyAction=null;t.MyFunc=null;t.MyActionEvent=null;// 非法,外部不能直接赋值 eventt.MyActionEvent?.invoke();//非法,外部不可以调用event标记的事件}}

这里:

t.MyAction=null;t.MyFunc=null;

是合法的。

但是:

t.MyActionEvent=null;t.MyActionEvent?.invoke();

会报错。

因为MyActionEvent被event关键字保护了,外部不能直接赋值。

外部只能这样:

t.MyActionEvent+=SomeFunction;t.MyActionEvent-=SomeFunction;

4. UnityAction 和 UnityEvent

4.1 UnityAction

理解了Action之后,UnityAction就很好理解了。

UnityAction是 Unity 内部预先声明好的委托类型。

它和Action很像。

Unity 内部大概是这样声明的:

namespaceUnityEngine.Events{publicdelegatevoidUnityAction();}

所以:

UnityActionaction;

本质上也是一个无参数、无返回值的委托。


4.2 UnityEvent

UnityEvent是 Unity 封装的一套事件系统。

它和普通委托的使用方式不太一样。

普通委托通常是:

+=-=?.Invoke()

而UnityEvent通常是:

AddListener RemoveListener Invoke

4.3 UnityEvent 的使用案例

usingUnityEngine;usingUnityEngine.Events;publicclassTest:MonoBehaviour{publicUnityEventMyEvent;voidStart(){MyEvent.AddListener(TestFunction);}privatevoidTestFunction(){Debug.Log("TestFunction");}}

调用事件时:

MyEvent.Invoke();

移除监听时:

MyEvent.RemoveListener(TestFunction);

4.4 UnityEvent 的特点

UnityEvent的一个重要特点是:

可以在 Unity Inspector 面板中显示,并且可以手动拖拽对象和方法进行注册。

这点是普通Action、delegate、event不具备的。

所以在 Unity 中,UnityEvent常用于:

  • 按钮点击事件
  • Inspector 面板配置事件
  • 不想写死代码,希望策划或美术可以在面板中配置回调
  • 简单的组件通信

5. Event 类

5.1 Event 和 event 不是一个东西

一开始我也容易把Event和event搞混。

后来查了一下才知道:

Event是 Unity 里的一个类,主要用于OnGUI系统。

它和 C# 的事件委托不是一回事。


5.2 Event.current

在 Unity 的旧版 IMGUI 系统中,每一帧 Unity 会多次推送输入、绘制等事件。

每一次都会生成一个Event对象。

可以通过:

Event.current

获取当前这一次 GUI 事件的数据。

例如:

voidOnGUI(){Evente=Event.current;if(e.type==EventType.MouseDown){Debug.Log("鼠标按下");}}

5.3 Event 常见用途

Event多用于:

  • OnGUI
  • 编辑器扩展
  • 自定义 EditorWindow
  • 自定义 Inspector
  • 旧版 IMGUI 输入处理

它和下面这些概念不是同一类东西:

delegateeventAction Func UnityEvent

所以可以简单记成:

event是 C# 事件关键字。
Event是 Unity 的 GUI 事件数据类。


6. 简单总结

6.1 delegate

delegate是委托类型。

它可以存储符合指定签名的方法,并在需要的时候调用。


6.2 event

event是对委托变量的一层限制。

它可以防止外部类直接赋值、清空和调用事件。

外部只能:

+=-=

6.3 Action

Action是系统封装好的无返回值委托。

例如:

Action Action<int>Action<int,string>

6.4 Func

Func是系统封装好的有返回值委托。

最后一个泛型参数表示返回值类型。

例如:

Func<int,int>Func<int,string,bool>

6.5 UnityAction

UnityAction是 Unity 自己封装的委托类型,和Action很像。


6.6 UnityEvent

UnityEvent是 Unity 封装的事件系统。

它可以通过代码注册监听,也可以在 Inspector 面板中配置监听。

常用方法是:

AddListener RemoveListener Invoke

6.7 Event

Event是 Unity 的 GUI 事件数据类。

它主要用于:

OnGUI Event.current EditorWindow 自定义 Inspector

它和 C# 的event关键字不是一个东西。


7. 最后总结

我现在对这些概念的简单理解是:

delegate:声明一种“方法变量类型” Action / Func / UnityAction:系统或 Unity 提前声明好的委托类型 event:限制外部访问权限的委托变量 UnityEvent:Unity 封装的、支持 Inspector 配置的事件系统 Event:Unity OnGUI / 编辑器系统中的事件数据类

相关新闻

  • 知识产权商标注册公司推荐:TOP5实力榜评测专业价格注意事项特点 - 品牌推荐
  • 济南打工人闲置黄金变现攻略,全城可上门回收省时又省心 - 开心测评
  • 2026 贵阳大小挖机出租公司 实测 TOP5 真实分享 - LYL仔仔

最新新闻

  • 3分钟让Word支持APA第7版:学术写作终极格式解决方案
  • 亨得利官方名表服务中心|官方热线及网点地址权威信息声明(2026年7月最新) - 亨得利官方博客
  • K9s v0.50.16 实战:5个高效运维场景与10个核心快捷键解析
  • 意义他指宇宙:让视界之外的静默被听见——从可观测的边界到不可见的基底,从看见到相信的认知跨越
  • 大气层Atmosphere 1.7.1:Switch自定义固件的终极配置与优化指南
  • WoW插件开发避坑指南:5个常见错误与性能优化方案

日新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号