用宏定义类似格式:

DECLARE_DELEGATE   //普通代理
DECLARE_DYNAMIC_DELEGATE_TwoParams //动态代理
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams //动态多广播代理 //多出的两个关键字的作用
In the case of multicast delegates,
any number of entities within your code base can respond to the same event and receive the inputs and use them. In the case of dynamic delegates,
the delegate can be saved/loaded within a Blueprint graph (they're called Events/Event Dispatcher in BP).

DYNAMIC:可以在蓝图里被序列化后定义和绑定操作。

MULTICAST:可实现一个事件类型多函数广播(事件类型必须声明为蓝图类型)

XXXParams:(使用DYNAMIC时)参数个数,宏定义参数里一个参数类型对应一个参数名字。

//声明位置(巩固下C++基础)

如果用到了静态事件类型的变量,因为需要在类外部声明这个变量,所以宏定义代理需要放在类外部。否则,随便放哪都行(在使用之前)。

注意:

1.当使用MULTICAST时,声明的代理事件类型需要声明为蓝图类型。不然报错,如:

//声明代理
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FLoadDesignsDelegateEvent, const TArray<FDesignInfo>&,
_designsInfo, const bool, _result); //声明代理事件类型
static FLoadDesignsDelegateEvent m_OnLoadDesignsEve; //调用代理事件
UFUNCTION(BlueprintCallable, Category = "BZone|SaveGameSystem")
static
void GetOneDesignFromServer(const FString &_userId, const FString& _desingId,const FLoadDesignDelegateEvent& _eve); //报错
F:/UE4_Projects/CGroupSystem_Server/Plugins/SaveGamePlugin/Source/SaveGamePlugin/SaveGame/Public/SaveGameBPLibrary.h()
: Type '{multicast delegate type}' is not supported by blueprint. Function: GetAllDesignsFromServer Parameter _event

2.调用时先检查下是否绑定了代理

RamaMeleeWeapon_OnHit.IsBound() 

新版本的:m_DelegateEvent.ExecuteIfBound(params...);

3.UObject和C++的不同绑定

不是MULTICAST:

//UObject
RamaMeleeWeaponComp->RamaMeleeWeapon_OnHit.BindUObject(this,&USomeClass::RespondToMeleeDamageTaken);
//C++
RamaMeleeWeaponComp->RamaMeleeWeapon_OnHit.BindRaw(this,&FSomeRawCPPClass::RespondToMeleeDamageTaken);

是MULTICAST:

TScriptDelegate<> t_de1;

t_de1.BindUFunction(this, STATIC_FUNCTION_FNAME(TEXT("ADrawHouseManager::Mouse_LeftOneClick")));

m_leftOneClickEvents.Add(t_de1);

并且Mouse_LeftOneClickDown();需要UFUNCTION()修饰,否则事件可以添加进代理,但不会进入函数(不在UE的函数列表里所以无法找到并执行)。

封装后的:

TMap<TMulticastScriptDelegate<>*, TScriptDelegate<>> m_bindEvents;

void ADrawHouseManager::AddBindEvent(TMulticastScriptDelegate<>* const _dele, const FString& _functionName)
{
if (_dele!=nullptr&&!_functionName.IsEmpty())
{
TScriptDelegate<> t_de;
FString t_str = "ADrawHouseManager::" + _functionName;
t_de.BindUFunction(this, STATIC_FUNCTION_FNAME(*t_str));
_dele->Add(t_de);
m_bindEvents.Add(_dele, t_de);
}
}

别忘记对象销毁时在析构函数里调用解绑!!!

void ADrawHouseManager::UnBindAllInputEventsFromPC()
{
if (m_bindEvents.Num()>)
{
for (auto it:m_bindEvents)
{
TMulticastScriptDelegate<>* t_dele = it.Key;
if (t_dele!=nullptr)
{
t_dele->Remove(it.Value);
}
}
}
}
ADrawHouseManager::~ADrawHouseManager()
{
UnBindAllInputEventsFromPC();
}

其余细节见:

https://wiki.unrealengine.com/Delegates_In_UE4,_Raw_Cpp_and_BP_Exposed  //C++代理事件

https://docs.unrealengine.com/latest/CHN/Programming/UnrealArchitecture/Delegates/index.html

[UE4]代理事件(C++)的更多相关文章

  1. 【JS深入学习】——事件代理/事件委托

    事件代理/事件委托(event delegation) 需求一:当一个div内部有多个事件发生,给每个元素逐个添加事件十分麻烦... 需求二:在项目中我们常常需要动态的添加元素,不可避免的需要为那些未 ...

  2. js委托事件和代理事件

    转载出处:https://www.cnblogs.com/liugang-vip/p/5616484.html js中的事件委托或是事件代理详解 起因: 1.这是前端面试的经典题型,要去找工作的小伙伴 ...

  3. 事件代理/事件委托----点击li弹出对应的下标和内容

    <body> <ul> <li>这是第一行</li> <li>这是第二行</li> <li>这是第三行</li ...

  4. AJ学IOS(07)UI之UITextField代理事件_类似QQ登陆窗口的简单实现

    AJ分享,必须精品 先看效果图: 学习代码 // // NYViewController.m // 05-UITextField事件_UIKit复习 // // Created by apple on ...

  5. [UE4]widget事件:On Mouse Enter、On Move Leave、Set Color And Opactiy

    只要是widget对象,都具有On Mouse Enter.On Move Leave事件

  6. [UE4]动画事件

    在动画中添加事件通知,在动画蓝图中就可以使用这个事件通知: 在动画蓝图中可以使用“Try Get Pawn Owner”取得控制的角色实例 在Controller中,可以使用“Get Controll ...

  7. 点击事件与UICollectionView的代理事件的冲突问题

    发现的问题:在UIImageView上添加UICollectionView视图,点击UICollectionViewCell,不执行didSelectItemAtIndexPath的代理方法. 解决方 ...

  8. UE4 代理 BindRaw和BindUObject

    代理允许您在C++对象上以通用的但类型安全的方式调用成员函数.通过使用代理,可以将其动态地绑定到任何对象的成员函数上,然后在该对象上调用函数,即时调用者不知道该对象的类型也没关系. 任何时候都应该通过 ...

  9. iOS——protoco和delegate (事件代理)

    一:被代理人personOne personOne.h #import <Foundation/Foundation.h> @protocol SomeThing<NSObject& ...

随机推荐

  1. Android2.1消息应用(Messaging)

    我想首先应该从AndroidManifest.xml文件开始,该文件是Android应用(APK)的打包清单,其中提供了关于这个应用程序的基本信息,如名称(application/@label),图标 ...

  2. [转]数据库更新(Update语句)查询

    2011-03-27 10:40:11| 分类: Database |举报|字号 订阅原文出自:http://blog.csdn.net/ylnjust02/archive/2005/12/10/54 ...

  3. Pandas 命令整理

    在网上看到一个整理的很好的pandas命令合集,转一份供自己查找与参考

  4. Python模块 实现过渡性模块重载

    本文是在阅读Python 学习手册后  感觉比较不错的一个实现模块重载的一个模块,该模块可以实现对已经加载在运行程序中的模块实现重新加载,并且该模块可以递归的实现对要重新加载的模块内所引用的其它模块的 ...

  5. Fluxbox 添加Qt应用程序menu

    /********************************************************************************* * Fluxbox 添加Qt应用程 ...

  6. 一年内自学MIT的33门课? 疯狂学习有方法

    [导读]能快速掌握复杂信息,对成就卓越事业至关重要.ScottYoung的学习过程不只适用于学生,同样有助于学习复杂技能的专业知识. 能快速掌握复杂信息,对成就卓越事业至关重要.ScottYoung的 ...

  7. Fire Game 双向bfs

    Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns) ...

  8. Sereja ans Anagrams 优先队列控制

    Sereja has two sequences a and b and number p. Sequence a consists of n integers a1, a2, ..., an. Si ...

  9. CTF-练习平台-Misc之 中国菜刀,不再web里?

    八.中国菜刀,不再web里? 下载文件后解压,是一个数据包,用wireshark打开,题中说的是菜刀,那就找http协议,首先过滤出http协议包 在第四个里面找到一句话木马 Flag应该在木马之后拿 ...

  10. 网络流--最大流dinic模板

    标准的大白书式模板,除了变量名并不一样……在主函数中只需要用到 init 函数.add 函数以及 mf 函数 #include<stdio.h> //差不多要加这么些头文件 #includ ...