Unity中的委托和事件(UnityAction、UnityEvent)

委托和事件

🎒什么是委托,委托的关键字是Delegate,委托是一种函数的容器,运行将函数做为变量来进行传递

通过Delegate关键字我们声明了一个无参无返回的委托,通过这个委托我们可以存储无参无返回的函数

csharp 复制代码
public delegate void myAction();

什么是多播委托,委托中可以存储多个函数,我们在调用这个委托时及多播委托,委托支持以下俩种用法,比较建议使用Invoke调用,这样可以明确知道这是一个委托,不容易和函数调用混淆

csharp 复制代码
myAction();
myAction.Invoke();

🎒什么是事件,有了委托那么进一步对委托进行安全封装就是事件,事件在委托关键字前加上event即可,那么事件和委托有什么区别,为什么要进一步封装呢

csharp 复制代码
public event delegate void myEvent();

事件不允许在类外部直接通过=赋值,也不允许在类的外部调用,这样可以避免直接暴露操作权限太大而被清空的情况,使用者只能通过一个个注册或注销来操作,保证了一种自产自销

特别的事件也不支持做为临时变量,所以我们只能声明为全局变量

C#封装

🎒在使用委托时每次都需要去声明对应的委托十分蛮烦,所以C#内部为我们封装了委托

包括了ActionFunc

csharp 复制代码
// 无参无返回的委托
Action action;
Action<int,int> act; // 有参数无返回委托
Func<int,int> func; // 有参有返回的委托

那么事件只需要加上event关键字即可

csharp 复制代码
// 无参无返回的委托
public event Action myEvent;

Unity封装

🎒C#已经为我们封装了那么Unity为什么又需要重新封装一个呢,委托事件设计之初并不会想到应用于Unity游戏开发所以没有形成一些方便Unity使用的编辑功能

这里我们可以先看一下UnityEvent的部分源码

csharp 复制代码
namespace UnityEngine.Events
{
  /// <summary>
  ///   <para>A zero argument persistent callback that can be saved with the Scene.</para>
  /// </summary>
  [Serializable]
  public class UnityEvent : UnityEventBase
  {
  	public void AddListener(UnityAction call) => this.AddCall(UnityEvent.GetDelegate(call));
    public void RemoveListener(UnityAction call) => this.RemoveListener(call.Target, call.Method);
    public void Invoke() { ... }
  }

👓️首先可以看见Unity封装了一个UnityEvent类,UnityEvent使用了Serializable特性,说明他是可以序列化的,我们声明一个公共的UnityEvent可以在Inspector窗口中看到

UnityEvent为我们提供了三个方法对事件进行注册注销和调用,UnityEvent是一个类,当我们设置为public时Unity会自动为我们进行实例化,但是如果是private私有时,就需要手动new为UnityEvent开辟空间了

👓️我们还能看见AddListenerRemoveListener传入的是一个UnityAction,UnityAction是Unity封装定义的一个委托,这里我们需要知道函数其实就是一个委托所以我们可以正常传入函数

👓️接着我们看一下UnityAction的源码是怎么样的,与C#封装的委托不同的是UnityAction最多支持四个参数

csharp 复制代码
namespace UnityEngine.Events
{
	/// <summary>
	///   <para>Zero argument delegate used by UnityEvents.</para>
	/// </summary>
	public delegate void UnityAction();
}
csharp 复制代码
namespace UnityEngine.Events
{
	public delegate void UnityAction<T0>(T0 arg0);
	public delegate void UnityAction<T0, T1>(T0 arg0, T1 arg1);
	public delegate void UnityAction<T0, T1, T2>(T0 arg0, T1 arg1, T2 arg2);
	public delegate void UnityAction<T0, T1, T2, T3>(T0 arg0, T1 arg1, T2 arg2, T3 arg3);
}
相关推荐
Duo1J2 小时前
【UE】Slate 编辑器工具开发03 - 节点编辑器 (EdGraph)
ue5·编辑器·游戏引擎·ue4
郝学胜-神的一滴3 小时前
[简化版 GAMES 104] 现代游戏引擎 02:拆解现代游戏引擎5+1层级架构,吃透引擎底层核心逻辑
c++·unity·架构·游戏引擎·图形渲染·unreal engine·系统设计
LONGZETECH4 小时前
新能源汽车充电设备装配与调试仿真教学软件 技术架构与核心实现解析
大数据·算法·3d·unity·架构·汽车
丁小未5 小时前
Unity 几种常见合批手段的要求
游戏·unity·合批·srpbatcher·动态合批·静态合批
旧物有情1 天前
游戏开发常用架构 #MVP,MVC
游戏·unity·架构·mvc
勇踏前人未索之境1 天前
Unity打包运行于鸿蒙手机
unity·智能手机·harmonyos
玖玥拾1 天前
Unity 3D 笔记(十一)UI 框架进阶:栈弹窗交互、BasePanel 基类虚方法、DoTween 界面动画
笔记·3d·unity
郝学胜-神的一滴1 天前
中级OpenGL教程 023:Assimp模型加载全解——从源码到架构的骈文探秘
c++·unity·游戏引擎·cmake·unreal engine·opengl
xcLeigh2 天前
Unity基础:GameObject与Component——Unity核心架构思想彻底理解
unity·教程·component·gameobject
郝学胜-神的一滴2 天前
中级OpenGL教程 022:探秘三维世界的血脉传承——物体父子关系与矩阵递归奥义
c++·线性代数·unity·矩阵·游戏引擎·unreal engine·opengl