用宏定义类似格式:

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. 电脑同时安装python2和python3, 如何实现切换使用

    由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼 ...

  2. Windows下使用Nexus搭建pypi私服

    Nexus之前一直作为maven的私服而被大家所熟知,但是其实nexus可以做很多种仓库的私服,官网的说明就揭示了一切,真是又方便又强大的开源工具. 首先下载安装nexus,地址: https://w ...

  3. 【Genymotion】add a new virtual device 失败

    Genymotion 新增虚拟设备(模拟器)时,由于网络原因,总是下载失败,如图: 下载失败提示“Unable to create virtual device: Connection timeout ...

  4. P1001 第K极值

    P1001 第K极值 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 成成第一次模拟赛 第一道 描述 给定一个长度为N(0<n<=10000)的序 ...

  5. 强化学习 CartPole实验的一些启发 有没有可能设计一个新的实验呢?(杆子可以向360度方向倾倒,可行吗?)

    最近在看强化学习方面的东西,突然想到了这么一个事情,那就是经典的CartPole游戏我们改变一下,或者说升级一下,那么使用强化学习是否能得到不错的效果呢? 原始游戏如图: 一点个人的想法: ===== ...

  6. 空格填充器(alignBySpace)

    /******************************************************************* * 空格填充器(alignBySpace) * 声明: * 1 ...

  7. Unity3D插件-自制小插件、简化代码便于使用(新手至高手进阶必经之路)

    Unity3D插件-简化代码.封装功能 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 FindT() ...

  8. EasyTouch中多种QuickGesture手势检测

    EasyTouch中QuickGesture的用法 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Qu ...

  9. uva1482:Playing With Stones (SG函数)

    题意:有N堆石子,每次可以取一堆的不超过半数的石子,没有可取的为输. 思路:假设只有一堆,手推出来,数量x可以表示为2^p-1形式的必输. 但是没什么用,因为最后要的不是0和1,而是SG函数:所以必输 ...

  10. JS校验 if (! temp_var) {} //拦截 ''和 undefined

    if (! aaa) {}  //拦截   ' '  和  undefined  和  0 不拦截null