一、蓝图-简易开关
- 实现开关的控制功能。实现思路是:在操作杆前按下
E
键后将把手朝下,然后打开宝箱。在上节实现打开箱子这个功能时,我们通过实现SGamePlayInterface
中的Interac
t函数来实现宝箱打开,因此对于操纵杆这个交互同样需要实现这个接口。 - 添加接口:在LeverBP的蓝图编辑器 -> 最上方的“类设置” -> “已实现的接口” -> 添加
SGamePlayInterface
类,此时在界面左侧“我的蓝图”中就会出现Interact
接口。右键Interact
接口 -> 实现事件,就会在事件图表中创建相应的节点。 - 将
HandMesh
拖拽进事件图表中创建节点,从该节点中拖拽以调用Set Relative Rotation
函数,从而改变把手的角度。而要改变的角度就用Make Rotator
节点来设置,其值根据效果需要取HandleMesh
的Pitch
值的相反数。
二、蓝图-打开宝箱
- 在左侧“我的蓝图” -> 变量中新建“
SelectedActor
”,用于存放需要打开的宝箱对象。在其右侧的细节面板中,将“变量类型”从布尔值更改为Actor
(蓝色图标),然后勾选“可编辑实例”,编译保存。这样就可以点击世界中的操纵杆模型,并在其右侧的细节面板中更加方便地设置该变量(从场景中选取宝箱即可)。 - 回到
SGameplayInterface.h
中,将void Interact(APawn* InstigatorPawn);
的宏变为UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
,保存编译,表示该接口可以在蓝图中被调用。
3.在蓝图中,获取该变量到事件图表中,调用SelectedActor的Interact(消息)
三、优化宝箱打开动画
- 打开宝箱TreasureChest的蓝图,在事件图表中添加Interact接口的实现,编译保存。此时运行关卡时无法打开宝箱
- 之前在代码中设置的
Interact
是BlueprintNativeEvent
,在C++中有默认实现,但在蓝图中允许覆盖,因此我们在蓝图中做出的修改其实是直接覆盖了C++代码的内容。若要在原基础上进行扩展,在蓝图中首先要调用原来的父函数(相当于代码中的Super
),这样原来打开宝箱的代码就可以重新被执行,具体操作为:在Interact
节点右键,选择“将调用添加到父项函数”,连线即可。 - 刚才的操作仅用于展示如何调用C++的函数,接下来会在蓝图中实现更好的宝箱打开动画。
- 在事件图表中选择“添加时间轴(
Add Timeline
)”节点,命名为AnimateLid
,用于控制宝箱盖子打开的动画。双击AnimateLid
节点进入动画编辑 -> 点击左上角“添加浮点型轨道”,命名为Pitch
-> 鼠标右键“添加关键帧”(或者按住Shift
+ 左键点击)。这个轨道用于控制宝箱LidMesh的Pitch角度,即控制每个时刻宝箱打开的角度(所以被称为时间轴)。 - 在其中添加
(0, 0)
和(0.5, 110)
两个点(110即为宝箱打开后Pitch的值,这个值可随意调整),在节点超过显示范围时可以点击“缩放进行水平/垂直匹配”两个按钮来调整比例。然后勾选“使用最后一个关键帧”,这样动画在播放到(0.5, 110)
后就结束了。 - 回到事件图表中,拖入
LidMesh
并调用Set Relative Rotation
节点控制其Pitch
值,并传入Make Rotator
节点的值,类似于之前调整操纵杆把手的操作。而Make Rotator
的Pitch
值就由时间轴节点AnimateLid
来控制,所以我们还需要把AnimateLid
的update
节点连接到Set Relative Rotation
的执行位置 - 编译后会得到
warning
:LidMesh
对蓝图不可见。因此我们需要在SurItemChest.h
声明LidMesh
变量前的宏定义修改为:UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
,是其变量可以暴露给编辑器使用。 - 时间轴:主要用于处理一些简单的、非动画任务,例如开门、改变光源或在场景中对Actor执行其他基于相关的操作。它们类似于关卡序列,因为它们都允许你在不同帧之间对浮点、向量、颜色的数值进行插值运算。
想了解更多案例可参照以下链接:
(1)实现灯光闪烁:https://dev.epicgames.com/documentation/zh-cn/unreal-engine/fading-lights-in-unreal-engine?application_version=5.2
(2)开门:
https://dev.epicgames.com/documentation/zh-cn/unreal-engine/opening-doors-in-unreal-engine?application_version=5.2
四、添加金块及效果
- 在蓝图编辑器中再添加一个静态网格体组件,分配给根节点
BaseMesh
,并命名为Gold
。然后为其分配网格体。 - 再添加一个“粒子系统组件”,分配给
Gold
,用于展示打开时爆出的金币。 给粒子系统的“粒子”设置为资源。随后,调整粒子系统的位置,使其播放的动画可以正常显示在金币上方。最后,在粒子系统的细节面板一直下拉,找到“细节”,并关闭“自动启用”,这是防止粒子特效一进入游戏就自动播放。 - 在事件图表中拖入粒子系统组件,调用“激活”函数,将
AnimateLid
节点的Finish
与“激活”函数的执行相连,这会在宝箱的Update
函数执行完毕后(即宝箱完全打开后)触发粒子特效。
时间轴的输出引脚:
(1)Update
(更新):一调用该时间轴就输出一个执行信号。
(2)Finished
(完成):当播放结束时输出一个执行信号。该引脚不会被Stop函数触发。
(3)Direction
(方向):输出枚举数据,指明了时间轴的当前播放方向。)
五、关闭宝箱
- 最后为打开的宝箱添加关闭的功能。在蓝图中有一个很适合这个场景的函数
Filp Flop
:可以实现在两个分支中自动依次切换(单词原意为触发器、翻转等,也很好理解),配合AnimateLid
节点中的Reverse
接口,可以实现动画的逆向播放,也就是关闭宝箱。
时间轴的输入引脚:
输入引脚
(1)Play
(播放):使得时间轴从当前时间处开始正向播放。
(2)Play from Start
(从开始处播放):使得时间轴从开始处正向播放。
(3)Stop
(暂停):在当前时间处停止播放时间轴。
(4)Reverse
(反向播放):从当前时间处反向播放时间轴。
(5)Reverse from End
(从结尾处开始反向播放) :从结尾开始反向播放时间轴。
(5)Set New Time
(设置新时间):将当前时间设置为New Time(新时间):输入中的设置的变量(或输入)。
(6)New Time
(新时间):该数据引脚取入一个代表时间的浮点值,以秒为单位,当调用Set New Time(设置新时间)输入时,时间轴可以跳转到该浮点值设置的时间处。
对
SetNewTime
的进一步理解的例子:
(1)角色瞬间移动到特定位置:
角色沿着一个预定路径移动。时间轴控制角色的位置变化。设置新时间可以让角色瞬移到指定时间的位置。
(2)进度条的动态跳转:
游戏中有一个进度条,显示任务的完成进度。玩家完成了一部分任务,进度条需要跳到对应的时间点的进度的位置。
(3)重放某一段动画:
游戏中有一个动画序列,例如角色的攻击动画。你希望在某个条件下重复播放某一段动画,而不是从头开始播放。时间轴跳到某段动画的开始时间点,开始重放这段动画。
- 根据测试结果,在关闭宝箱时粒子特效仍然被触发了(我们并不需要这样)
- 优化方法:在触发粒子系统前判断
Flip Flop
节点Is A
的值,是前者A就执行(激活)特效,否则不执行