【干货分享】UE5虚幻引擎:蓝图通信详解,轻松掌握必备技能!

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:UE虚幻引擎专栏
  • 💥 标题:【干货分享】UE5虚幻引擎:蓝图通信详解,轻松掌握必备技能!
  • ❣️ 寄语:人生的意义或许可以发挥自己全部的潜力,所以加油吧!
  • 🎈 最后:文章作者技术和水平有限,如果文中出现错误,希望大家能指正

0 引言

  • 问题:为什么需要掌握蓝图通信?
  • 答案:在开发一个项目时,总是会遇到一个蓝图对象需要获取另一个蓝图对象的属性值或者函数功>能等。例如,在制作一个开关门时,人物蓝图就需要调用门蓝图的一些功能。
  • 蓝图通信的四种方式:直接蓝图通信事件分发器蓝图接口蓝图转换(castTo**)

1 直接蓝图通信

  • 直接蓝图通信其实还有几种方式,下面一一介绍。
  • 缺点:是只能实现一种蓝图和另一种蓝图通信,不能实现一对多的通信方式。

1.1 在关卡蓝图中直接拖拽Actor

  • 这种方式只有在关卡蓝图中才能使用,因为只有关卡蓝图才能直接将本关卡中的Actor直接选中拖入蓝图中,如下图所示:
    在这里插入图片描述
  • 然后可以将两个需要通信的Actor都拖拽到关卡蓝图中,然后进行属性或函数的访问。

1.2 Get Actor of Class/Get All Actors of Class

  • 利用Get Actor of Class(获取类的Actor)或Get All Actors of Class(获取类的所有Actors)这两个节点获得场景中的Actor。
  • 这两个节点的区别是一个获取一个Actor(第一个实例化的Actor),另一个是获取所有实例化的Actor。
  • 案例:两个蓝图,一个是BP_Pawn,一个是BP_Door,BP_Pawn需要调用Door蓝图中的OpenDoor函数,来实现开门的功能。
    在这里插入图片描述

2 事件分发器

  • 事件分发器(Event Dispatchers)可以实现一对多的蓝图通信方式,功能更加强大
  • 其实事件分发器这个功能和MFC的消息/事件机制类似,和QT中的信号槽机制类似。所以学习过类似的编程思想的话,学习这个会更好上手。
  • 使用场景:在一个游戏关卡中,一个BOSS的死亡,往往会触发很多功能,例如,爆装备、打开隐藏机关、人物升级等等。这就是一个事件发生后触发很多其他事件。这个业务就能使用事件分发器来实现。
  • 使用步骤:在BOSS蓝图中创建一个事件分发器(EP_BOSSDead),然后机关蓝图、人物蓝图等其他需要响应BOSS死亡事件的蓝图中,绑定EP_BOSSDead事件分发器。

2.1 创建事件分发器

  • 在BP_BOSS蓝图中创建事件分发器EP_BOSSDead。点击图中的加号即可。
    在这里插入图片描述

2.2 绑定事件分发器

  • 首先通过直接蓝图通信的方式获取BP_BOSS蓝图对象,然后绑定事件分发器。
  • 绑定事件分发器的可以是事件,也可以是函数。(大家可以自己去试试)
    在这里插入图片描述

2.3 调用事件分发器

  • 调用事件分发器,Call ****,即可。事件分发器被调用后,之前和该事件分发器绑定的事件/函数,都会被调用。
    在这里插入图片描述

3 蓝图接口

  • 问题:什么情况需要使用蓝图接口?
  • 答案:当同样的操作,需要不同的响应时,就可以使用蓝图接口(其实概念和C++中的多态一样)。例如,玩家按下键盘E键时,物体会被拾取,NPC会与玩家对话,等等。又或者子弹击中不同目标时响应不同,油桶会爆炸,NPC会死亡等等。

蓝图接口特性

  • 蓝图接口(简称 接口)是一对一通信方式,这点需要注意。
  • 蓝图接口是函数的集合体,只有 函数 名称没有 函数 实现。(其概念和C++中的接口基本一样,C++的接口。C++抽象类是至少有一个纯虚函数即可,还可以有属性值)
  • 和C++中抽象类的区别:子类继承一个蓝图接口后,不重写接口函数,也能实例化(创建对象)。但是C++子类不重写父类的纯虚函数是无法实例化的。
    在这里插入图片描述
  • 蓝图接口通信的前提:①需要有被通信放的引用;②被通信方实现了蓝图接口函数;
  • 从上一点通信前提不难看出,其实蓝图接口通信本质上还是直接蓝图通信,只不过是获取被通信方的引用后调用了蓝图接口函数而已。(所以不知道,为什么虚幻官方要单独将蓝图接口列为一种通信方式,可能比较特殊吧)

3.1 使用步骤

  1. 创建一个蓝图接口,是全局的。名叫(BPI_MyInterface),同时新建一个接口函数OnTakeWeaponFire(只有名称,参数信息,没有函数具体实现)
    在这里插入图片描述
  1. 需要使用蓝图接口的类,在类设置(Class Setting)中继承该接口
    在这里插入图片描述
  1. 编译蓝图后,再重写接口函数。(不编译蓝图的话,找不到接口函数)
    在这里插入图片描述
    在这里插入图片描述
  1. 获取被通信方的引用,然后通过引用调用接口函数(接口函数会出来两种,不要选错了,看下面图片)
    在这里插入图片描述
    在这里插入图片描述

3.2 为什么要使用蓝图接口

  • 思考:既然 直接通信蓝图接口 都是要先获取对象的引用再去调用函数,那直接调用类成员函数,和调用类的接口函数有什么区别呢?
  • 解答:方便调用,降低程序耦合。假如使用直接调用类成员函数的方式来通信,在收信方(上面叫做被通信方)做的工作没有区别,都是实现响应函数而已。但是发信方所做的工作就繁琐了,需要知道对象的具体类型。
  • 这个问题的同等于为什么需要多态?
  • 如何实现多态:基类指针指向子类对象,然后调用纯虚函数,实现多态!!!
class animal
{
public:
    virtual void name() = 0;
};

class cat : public animal
{
public:
    virtual void name()
    {
        std::cout << "cat\n";
    }
private:
    int a;
    double b;
};

class dog : public animal
{
public:
    virtual void name()
    {
        std::cout << "dog\n";
    }
};

void name(animal* MyNimal)
{
    // 基类指针指向子类对象,然后调用纯虚函数,实现多态!!!
    MyNimal->name();
}

int main()
{
    // animal是抽象类,是不能实例化对象的。但是可以抽象类定义指针!!!
    // 原因:编译器在编译时需要了解类的所有信息以便准确的为要实例化的对象分配内存;
    //       由此可见,定义一个类对象是要生成一个类的实例的,而C++规定抽象类是不能实例化的。
    //       但是抽象类指针的内存大小是可以确定的,因为指针都是4个字节。
    animal* cat1 = new cat();
    animal* dog1 = new dog();
    name(cat1);
    name(dog1);
}

4 蓝图转换

  • Cast To *(类型转换为),其实就是将父类对象类型转换为子类对象类型。因为有些时候获取的并不是具体的子类对象,而是父类对象。
  • 例如Event Hit事件返回的Hit结构体中的Hit Actor变量就是一个父类类型,因为这样设计可以大大降低程序的耦合性,因为谁也不知道以后会有多少种类是集成Actor的,不可能把每一种子类都重写一个函数,这样程序设计效率非常低。
    在这里插入图片描述
  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很好,以下是程序员常访问的国外技术交流网站汇总: 1. Stack Overflow:这是最受欢迎的技术问答网站之一,有大量的程序员在这里寻求帮助和提供答案。 2. GitHub:这是一个代码托管平台,许多开源项目都在这里托管,程序员可以在这里学习和贡献代码。 3. Reddit:这是一个社交新闻网站,有各种技术相关的子版块,程序员可以在这里交流和分享经验。 4. Hacker News:这是一个由Y Combinator创办的社区,聚集了许多技术创业者和程序员,讨论各种技术和商业话题。 5. CodePen:这是一个在线代码编辑器,程序员可以在这里创建和分享自己的代码片段,还可以参加各种编程挑战和竞赛。 6. Medium:这是一个博客和内容分享平台,有许多技术作者在这里发布文章和教程,程序员可以在这里学习新技术和分享自己的经验。 7. Dev.to:这是一个由开发者社区创建的博客平台,有许多技术作者在这里发布文章和教程,还可以参与各种讨论和交流。 8. Codecademy:这是一个在线编程学习平台,提供各种编程语言和技术的课程和项目,程序员可以在这里提升自己的技能。 9. Udacity:这是一个在线教育平台,提供各种计算机科学和技术相关的课程和项目,程序员可以在这里深入学习和实践。 10. Coursera:这是一个在线教育平台,提供各种计算机科学和技术相关的课程和项目,还有许多知名大学和企业提供的课程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值