一、什么是蓝图通信?
在开发一个项目时,总是会遇到一个蓝图对象需要获取另一个蓝图对象的属性值或者函数功能等。例如,在制作一个开关门时,人物蓝图就需要调用门蓝图的一些功能。
蓝图通信的四种方式:直接蓝图通信、事件分发器、蓝图接口、蓝图转换(castTo**)。
二、直接蓝图通信
2.1 在关卡蓝图中直接拖拽Actor
这种方式只有在关卡蓝图中才能使用,因为只有关卡蓝图才能直接将本关卡中的Actor直接选中拖入蓝图中,如下图所示:
然后可以将两个需要通信的Actor都拖拽到关卡蓝图中,然后进行属性或函数的访问。
2.2 Get Actor of Class/Get All Actors of Class
利用Get Actor of Class(获取类的Actor)或Get All Actors of Class(获取类的所有Actors)这两个节点获得场景中的Actor。
案例:两个蓝图,一个是BP_Pawn,一个是BP_Door,BP_Pawn需要调用Door蓝图中的Open Door函数,来实现开门的功能。
三、事件分发器
- 事件分发器(Event Dispatchers)可以实现一对多的蓝图通信方式,功能更加强大。
- 使用场景:在一个游戏关卡中,一个BOSS的死亡,往往会触发很多功能,例如,爆装备、打开隐藏机关、人物升级等等。这就是一个事件发生后触发很多其他事件。这个业务就能使用事件分发器来实现。
- 使用步骤:在BOSS蓝图中创建一个事件分发器(EP_BOSSDead),然后机关蓝图、人物蓝图等其他需要响应BOSS死亡事件的蓝图中,绑定EP_BOSSDead事件分发器。
3.1 创建事件分发器(发送方)
在BP_BOSS蓝图中创建事件分发器EP_BOSSDead。点击图中的加号即可。
3.2 绑定事件分发器(接收方)
- 首先通过直接蓝图通信的方式获取BP_BOSS蓝图对象,然后绑定事件分发器。
- 绑定事件分发器的可以是事件,也可以是函数。(大家可以自己去试试)
3.3 调用事件分发器(发送方)
四、蓝图接口
问题:什么情况需要使用蓝图接口?
答案:当同样的操作,需要不同的响应时,就可以使用蓝图接口(其实概念和C++中的多态一样)。例如,玩家按下键盘E键时,物体会被拾取,NPC会与玩家对话,等等。又或者子弹击中不同目标时响应不同,油桶会爆炸,NPC会死亡等等。
注:个人感觉直接通信方式和接口通信差不太多。
4.1 使用步骤
4.1.1 外部创建蓝图接口
我的理解是蓝图接口和C++中的接口类似,是一个纯抽象类。
创建一个蓝图接口,名叫 BPI_MyInterface,同时新建一个接口函数OnTakeWeaponFire(可以理解为C++中的纯虚函数)
4.1.2 接收方蓝图继承接口
需要使用蓝图接口的类,在类设置(Class Setting)中继承该接口。
注:我的个人理解是 Door 和 Oil 这两个蓝图类针对 On Take Weapon Fire 这个函数做了不同的处理,然后发送方蓝图(首先获取不同引用)可以调用接口函数实现不同的功能。
4.1.3 发送方蓝图调用接口函数
思考:既然 直接通信 和 蓝图接口 都是要先获取对象的引用再去调用函数,那直接调用类成员函数,和调用类的接口函数有什么区别呢?
解答:方便调用,降低程序耦合。假如使用直接调用类成员函数的方式来通信,在收信方(上面叫做被通信方)做的工作没有区别,都是实现响应函数而已。但是发信方所做的工作就繁琐了,需要知道对象的具体类型。
这个问题的同等于为什么需要多态?
如何实现多态:基类指针指向子类对象,然后调用纯虚函数,实现多态!!!