UE委托函数
参考:
单播
虚幻的委托分为三类,分别为单播、多播和动态多播。单播顾名思义就是一次只能绑定一个函数的委托,多播能一次性绑定多个,动态多播即可以在蓝图中进行动态的绑定且可以绑定多个。
单播委托
单播委托是“一对一”的。 它只能绑定一个函数,如果你绑定了第二个,第一个就会被覆盖。
- 特点: 效率最高,支持返回值(这是多播做不到的)。
- 适用场景: 需要从一个函数获取结果,或者明确只需要一个回调。
- 注意: 不能在蓝图中使用(即不能加
BlueprintAssignable)。
实现
新建一个Actor类的DelegateActor类进行测试
定义类型
单播可以定义带参数、返回值和参数+返回值三类委托,如下代码所示,分别定义了这三类单播委托,所有的说明见注释部分,定义的位置在头文件和类之间
1 | DECLARE_DELEGATE_[RetVal]_[Param个数]([返回值类型], 委托名, [形参1类型], [形参2类型],...) |
添加参数RetVal可以有返回值,只有添加这个参数才能有返回值类型,也只有单播可以加这个
添加Param个数可以指定被委托函数的形参个数,比如一个OneParam,上限为9个,比如NineParams,不写即没有形参
声明委托类型变量
上述定义的可以将其看作是一个类型定义,要真正使用还需要在类中声明该类型的变量,格式为
1 | 委托名 变量名 // 这里变量名甚至可以和委托名相同,但不要这样,会出问题 |
定义委托需要绑定的函数(被委托的函数)
这里没什么好强调的,就是定义的函数要和对应的委托保持一致的返回值和参数,没有返回值的委托用void就好
比如
1 | void AClassB::HandleScore(int32 NewScore) |
在构造函数或其他初始函数中进行绑定
有很多种绑定函数的方法,这里说常用的BindUObject
使用委托变量.BindUObject(ObjectPointer, &ClassName::FunctionName)
其中ObjectPointer为被委托函数的对象的指针&ClassName::FunctionName:为目标函数的成员指针。必须包含类名空间(例如 &AMyActor::MyHandler)
比如在AClassA 中绑定 AClassB 的函数
1 | // 在 ClassA.cpp 中 |
而HandleScore()就要求其形参和返回值与ScoreDelegate的类型定义时一样
执行
执行时,有返回值和没返回值使用的执行函数不同
没返回值使用ExecuteIfBound()
1 | 委托变量.ExecuteIfBound(实参1, 实参2,...) |
而有返回值使用Execute()
1 | 委托返回值类型 a = 委托变量.Execute(实参1, 实参2,...) |
解绑与绑定新的函数
解绑:委托变量.Unbind();
绑定新函数和绑定函数一样用BindUObject
其他绑定函数方法

示例参考这个文章
多播委托
多播委托是“一对多”的。 它可以同时绑定多个函数,触发时所有函数按顺序执行
- 特点: 没有返回值(void),因为无法确定该返回哪一个函数的结果
- 适用场景: 广播事件,比如“玩家升级了”,这时 UI、音效、特效系统都需要同时收到通知
实现
定义多播委托
1 | DECLARE_MULTICAST_DELEGATE_[Param数量](委托名, [形参1类型], [形参2类型],...) |
声明委托类型变量、绑定被委托函数
1 | //多播代理声明 |
绑定&执行
绑定使用委托变量.AddUObject(ObjectPointer, &ClassName::FunctionName)函数可以添加绑定函数,多播函数的特点就如此,可以绑定多个函数,接着按队列触发(先进先出)
执行使用委托变量.Broadcast()
动态多播委托
在 UE5 开发(尤其是涉及到 C++ 与蓝图混编)时,它最常用,这里的“动态”不是指内存分配,而是指 “动态反射”。
- 普通多播:在编译后,它就是一串硬编码的函数指针地址。
- 动态多播:它存储的是函数的名字(字符串)。在运行时,它会去 UClass 的元数据(函数列表)里查找这个名字。
实现
定义动态多播委托
1 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_[Param个数](委托名, 形参1类型, 形参1名称, 形参2类型, 形参2名称) |
- 必须以 F 开头:委托类型名必须符合 Unreal 命名规范。
- 必须带参数名:如前所述,宏里必须写成 (类型, 名字)。
- 变量必须在UPROPERTY里加上 BlueprintAssignable:如果你想在蓝图里看到它,这样可以用bind节点绑定事件
- 在UPROPERTY里加上BlueprintCallable可以使委托在蓝图里用call节点调用和解绑
1
2//动态多播委托,区别在于它可以暴露给蓝图,在蓝图中进行事件的绑定
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDynamicMulDelegate, FString, param);//一个参数的动态多播委托,名称一定要F开头不然会编译报错“Delegate type declarations must start with F”1
2
3//动态多播代理变量声明
UPROPERTY(BlueprintAssignable, BlueprintCallable)
FDynamicMulDelegate DynamicMulDelegate;
绑定函数/事件
蓝图
动态多播最大的特点就是可以在蓝图中使用Bind或Assign节点绑定事件,使用Unbind节点解绑事件,当然,被绑定事件也需要有和委托定义时一样的形参
还可以使用Call节点执行委托
这样,将Actor放入场景后运行便会打印文本Hello
cpp内
动态多播只可以用AddDynamic或AddUniqueDynamic来绑定函数
使用Broadcast()来执行委托AddUniqueDynamic将会判断当前函数是否绑定过,若绑定过将不会再次绑定
1 | DynamicMulDelegate.AddDynamic(this, &ThisClass::MyFunction); |
接着使用Broadcast()执行委托
1 | DynamicMulDelegate.Broadcast(TEXT("Hello")); |
绑定和执行cpp与蓝图可以互通,这就是动态绑定的强大之处