【ue4】【蓝图】通信篇
前言
上回书说到,我们可以使用蓝图的流程控制结构来实现一些比较复杂的逻辑,甚至是算法过程
但是这只是作为学习熟悉的一个环节,而非用药于实际开发中
当我们理清一个蓝图内部的一些控制之后,我们难免会想再进一步研究一下怎么搓和两个蓝图的人生大事,
再长远一点地看,我们以后难免还要操心解蓝图和CPP之间的关系
这就像人到了中年,操办完了儿子的婚事,还要再操心着女儿的婚事一样
我们这里就顺着这个思路去学习蓝图
本篇主要整理一下蓝图之间的通信方法,关于CPP的部分以后再说。
直接蓝图通信
概念
当我们想要在一个蓝图里访问另一个蓝图中包含的
函数事件变量等时我们可以直接引用一个目标蓝图
即在 当前蓝图 里创建一个 目标蓝图 类型的变量
然后暴露这个变量
这样就可以在外面给这个变量赋值,使其直接引用一个 目标蓝图 变量
我们来看一个例子
我分别新建两个蓝图 bp_01 和 bp_02
并且分别添加一个 Geometry 作为它们的 RootComponent

我们把它们放在世界里,并使其紧贴地面

现在我想实现的效果是,当我们控制角色经过 bp_01 的时候
bp_01 触发 其 overlap 事件,使它所引用的 bp_02 实例向上移动100个单位
那么我们就需要 bp_01 可以访问的到 bp_02, 这就是我们的目的了
首先我们打开 bp_01 蓝图,新建一个变量,并将变量类型其指定为 bp_02 的 Object 类型

我们将这个变量暴露给外界,并设置它的 工具提示

直接点变量右边的 小眼睛 也可以

这个时候,我们就可以认为 bp_01 已经有了引用 bp_02 的能力,换句话说
bp_01 可以引用任何一个类型为 bp_02 的蓝图类
那么我们可以写触发事件了,注意在这之前要将 bp_01 的 Collision 设置为 overlapOnlyPawn, 意思是只有 Pawn 类型可以通过它
触发事件如下

我们点击世界里的 bp_01实例,在其 细节 栏里选择 bp_02实例

测试一下,当我们的 Character 走到 bp_01 上时,bp_02 向上移动了100个单位

注意
如果要在
关卡蓝图上引用一个蓝图,只需要在世界中选中这个蓝图实例,然后在关卡蓝图的事件表中右键,即可看到创建引用的选项
再次注意
由于在CPP中,父类引用可以指向子类,所以我们这里也可以将
bp_01中的变量设置为bp_02的父类类型,如ACtor这个时候如果我们想使用子类特有的方法的话,就需要向下转型
还要注意一下
当我们新建一个函数时,可以将另一个蓝图类型作为函数的输入参数
这样在函数里就可以使用另一个蓝图类
类比于CPP的函数

使用场景
按开关(bp_01) 就可以打开门或灯(bp_02)
及其他 -- 两个 actor 需要相互通信
事件调度/分配器
概念
事件分配器被调用时,与它绑定的全部事件都会被调用
主要用于从单一源同时执行多个事件
我们来看一个例子
我们把前面的方法改成使用事件分配器试一下
首先,我们创建一个事件分配器

然后我们把它拖到事件图表中去,可以看到有好几个选项

我们选择 分配, 会出现一个 分配节点 和一个 自定义事件 节点
可以任意多次使用此节点

一旦绑定成功,每当我们调用此事件分配器时,就会调用所以与其绑定的事件
我们在 overlap 触发的时候调用此事件分配器,就实现了和上面一样的效果

CPP话外音 --
在CPP里,这个相当于
AddDynamic函数的调用,我试了一下,同一个事件分配器确实可以多次调用AddDynamic
1 | welcome_ui->start_bt->OnClicked.AddDynamic(this, &ADGameGameModeBase::on_welcome_start_clicked); |
使用场景
来自官网的经验,(来自实际的经验暂时还没有,这辈子都不会有的, 爱咋咋的^_^)
需要从角色蓝图到关卡蓝图进行通信
玩家升级后,开放之前的锁定区域
玩家按下某个按键后,对关卡执行某种操作
生成的
Actor执行某种操作时触发事件
生成一个
Boss,Boss被消灭时触发一系列的事件 -- 掉装备 加经验,地图状态刷新 等等在关卡中生成一个道具(武器,回复剂等),并在道具被拾起时告知道具和角色
蓝图接口
概念
可类比于面向对象里的接口、
可以对 共有某些特征 但又 各不相同 的对象使用一种通用的方法交互
而这些对象又可重新定义接口的实现,以表达出不同的实现
我们来看一个例子
我们现在要实现一个简单的东西体验一下接口的用法
我们现在有两个
Actor还有一个
Actor用来触发事件,当我们的角色移动到这个Actor上面的时候,就会触发另外两个物体的移动事件但是它是直接用
Get All Actors With Interface来获取所有实现了某个接口的物体,但并不知道物体本身是什么它的事件图表看起来是这样的

而前面那两个物体则实现了同一个接口,但是他们都重写了此接口的函数
所以当我们移动到第三个物体的时候,另外两个物体会朝不同的方向移动
我们首先来建立一个接口,并添加一个接口函数 running
然后在那两个物体的 类设置 里,都添加这个接口

这两个类的事件图表看起来像这样


然后运行一下,我们会发现,当我们的角色 overlap 到第三个物体上时,另外两个物体分别朝前面和右面移动

这就是接口最简单的例子了
使用场景
- 数个蓝图中存在一些相似功能,但在调用后执行不同的效果
- 玩家拥有一个喷射器,使用时会触发
Damage事件, 树木和雪人蓝图都实现这个接口,但表现不同的效果 - 玩家拥有一个
use按钮,按下可执行 开门 ,关灯, 拾起道具等操作 - 敌人拥有特殊能力,可基于玩家的体力值完成变化,执行不同的操作
- 玩家拥有一个喷射器,使用时会触发
蓝图投射
概念
Cast to类型转换节点 -- 询问对象是否为该对象的特殊版本
使用场景
- 需要访问另一个蓝图的特殊版本。
- 角色走进火焰中,导致体力值耗尽。
- 投射到特殊的角色蓝图,以便访问并变更体力值。
- 角色死亡,需要重新生成。
- 投射到特殊的游戏模式蓝图,执行重新生成脚本。
- 角色走进火焰中,导致体力值耗尽。
- 需要访问相同类的多个蓝图,并以相同方法进行修改。
- 场景中拥有数盏灯,事件发生时需将它们开启或关闭。
- 投射到灯蓝图并执行函数将灯关闭。
- 场景中拥有数盏灯,事件发生时需将它们开启或关闭。
- 需要访问一个特殊的子蓝图。
- 存在基于一个动物蓝图(猫、狗、鸟)的数个蓝图,需要访问其中一个动物。
- 投射到猫、狗和鸟,访问其相应的蓝图和特有功能。
- 存在基于一个动物蓝图(猫、狗、鸟)的数个蓝图,需要访问其中一个动物。
总结
今天写的这些,都是很基础的概念上的东西
但是实践出真知,要想真正了解蓝图通信,为进一步深入学习 ue4 作打算
还需要不断地在实践中尝试才好
共勉 \(o)/

