蓝图通信二

创建独立的蓝图类实现蓝图间的互相通信

****的博客添加图片太麻烦了,而且链接网页图片会出现错误,如果需要看详细文章,请访问我的微信公众号《猎梦虚幻研究社》

在第一篇中,介绍了通过关卡蓝图来实现蓝图间的数据交互和事件通知。

但是从我介绍关卡蓝图开始就表明了我不推荐使用这种方式的态度。当一个场景中有极其多的门或者灯需要控制,或者有更多的场景元素需要我们操控时,使用关卡蓝图明显是一个十分糟糕的决定,这会让你的关卡蓝图变得无比复杂,臃肿,并且让你难以提起兴趣去维护它。

所以从现在开始,与蓝图通信有关的事将会变更到独立的蓝图类之间来实现(独立的蓝图类就是指单独创建的蓝图,比如在内容浏览器点击鼠标右键创建一个Actor蓝图)。

这一篇将通过蓝图中的变量来指定场景中的物体,以此来实现与第一篇中通过关卡蓝图实现“开门”一模一样的功能。

所以第一步需要做的是新建一个Actor蓝图,用它来作为我们的触发器。
蓝图通信二
创建Actor蓝图的方法以后就不赘述了,在内容浏览器右键点击创建蓝图,选择Actor为父类。我在这里将它命名为BP_OpenDoor。

打开这个蓝图,在组件部分添加一个StaticMesh组件用来存放我们的模型(如果你需要使用的话),再创建一个Box Collision组件作为碰撞体。

这个Box Collision和之前使用的Box Trigger相同,不会阻挡玩家移动,不会被看见,又可以触发事件。

如果到这一步没有出错的话,你的组件面板应该有如下图两个物体:
蓝图通信二

给StaticMesh一个你预备好的模型,调整Box的大小来适应模型。我就用一个简单立方体来表示开关,我调整好以后的状态如下图:
蓝图通信二

模型方面的工作就完成了,现在我们来到事件图表。

首先添加一个变量,类型更改为Actor并且将其设置为public。
蓝图通信二
现在这个变量存储的就是一个以Actor类作为基类的对象,所有继承于Actor的类都可以被存放在这个变量里。这么说可能非程序员有些不能理解,那么只要知道,一会儿我们要创建的Actor蓝图或者直接拖放的StaticMesh当做门,可以用这个变量来存储即可。

和关卡蓝图中逻辑相同,我们还需要一个Vector来存储门原本的位置。
蓝图通信二

在组件面板中,选中我们创建的Box Collision,在细节面板的最底下会有BeginOverlap事件
蓝图通信二
与关卡蓝图中的操作相同,点击加号添加这个事件(我的布局是为了截图方面临时调整过,可能与你的页面布局不太相同)。因为我们需要实现的功能是进入范围打开门,然后离开区域,所以这里只添加BeginOverlap事件,而不添加EndOverlap事件。

具体蓝图逻辑的写法:

先在BeginPlay的时候记录一下门的初始坐标:
蓝图通信二
然后将蓝图连接成如下图所示的样子:
蓝图通信二

现在我们来整理一下上述步骤的逻辑:

我们新建了一个Actor类(BP_OpenDoor),在其中创建了一个Box Collision作为我们重叠事件的触发器。将这个类放在场景中,场景中对应位置就会出现我们的模型和触发器Box Collision。当玩家进入触发器时,我们要想办法将“门”打开。

在蓝图里,创建一个变量(AimActor)来代表我们要操作的“门”,在游戏开始时(BeginPlay)获取我们对应“门”(AimActor)的坐标并用变量(Location)记录下来,当玩家进入范围触发重叠事件(BeginOverlap)后,设置“门”的移动,方法和第一篇中使用Timeline相同。

这样BP_OpenDoor的逻辑就完成了,现在要做的就是想办法指定我们场景中的“门”,并且记录在AimActor变量中。这样当我们操作这个AimActor时,实际上就是在操作我们指定的“门”。

指定“门”的方法其实也十分简单。我们已经将BP_OpenDoor蓝图放置到场景中,选中它时,可以在细节面板中看到AimActor这个属性。在这个属性旁边由一个小吸管(或者称为取色管)
蓝图通信二
点击它,再点击场景中我们已经放置好的“门”,这样就成功指定了模型,并且将它的引用和BP_OpenDoor中的变量关联了起来。
蓝图通信二
这样就实现了和之前相同的功能。
蓝图通信二

现在我们完成了对关卡蓝图的简化,释放了关卡蓝图中的空间,降低了逻辑的耦合性。关卡蓝图可以有更多的空间来编写真正需要的逻辑,而这种交互则独立封装起来,仅在BP_OpenDoor和“门”之间相互交互,不再干扰到其他部分。

这是一个很好的思路,在官方案例Content Example中也有大量的类似应用
蓝图通信二
只不过它用到了一些更深的方法(蓝图接口和事件调度器),没有封装的这么简陋而已。

这一篇的主要目的是向功能的封装走出第一步,将功能从关卡蓝图转移到独立的蓝图类中。后续将会介绍其他方法,来提高它的封装程度,进一步降低各个蓝图类之间的耦合性。

蓝图通信二