到目前为止,你一直在使用后期处理体积来调整预先存在的设置,以控制场景的整体视觉效果。 要添加自定义后期处理效果,你可以创建一个后期处理材质。 材质随后可以将该效果应用到摄像机,或添加到Post Process Volume中,从而影响玩家在屏幕上看到的画面。
在本系列教程的这一部分,你将添加一个效果,用于在玩家受到伤害时,在屏幕上直观地表现受伤状态。 屏幕边缘会呈现出红色的脉动效果。 随着玩家生命值降低,效果会增强并占据更多屏幕空间。
要实现此功能,你需要:
构建一个父级后期处理材质。
创建一个材质实例,用于控制父材质中的各个参数。
使用蓝图可视化脚本显示并控制屏幕效果。
修改玩家角色的蓝图逻辑,使其在一段时间后恢复生命值,从而使受伤视觉效果消失。
开始之前
请确保你已理解《解谜冒险游戏美术创作指南》教程系列的前几节中涵盖的相关内容:
构建材质和材质实例。
将后期处理体积添加到关卡中。
你将在示例项目文件中使用以下资产:
BP_AdventureCharacter蓝图
创建用于显示伤害效果的材质
首先,你需要制作一个材质,作为定义效果外观的基础。 材质会生成一个灰度遮罩,使游戏内摄像视角显示在遮罩的较亮区域,而脉动的红色伤害效果出现在遮罩的较暗区域。
要创建新的后期处理材质,请执行以下操作:
在内容浏览器中,转到AdventureGame > Artist > Materials文件夹。
在Materials文件夹中,创建一个新的Material资源,命名为
M_Screen_Damage。 打开这个材质。在细节面板中,将材质的Domain更改为Post Process。
你会注意到这改变了材质根节点上可用的引脚。 对于后期处理材质,你只需要控制自发光颜色,因为这些材质不使用场景光照。
在Surface类型的材质中,自发光颜色会控制材质发出的光量。 当你将材质的Domain更改为Post Process时,它将不再为表面着色,而是直接写入屏幕。 在这种情况下,自发光颜色控制每个像素的最终输出颜色。
定义伤害效果形状
现在,你将开始构建材质图,从定义后期处理效果形状的遮罩开始。 首先,使用GeneratedRoundRectNode绘制一个灰度遮罩,其形状为圆角矩形——内部为白色,外部为黑色。 稍后,你将定义遮罩各部分显示的内容。
要创建灰度遮罩,请执行以下操作:
在材质图表中,在材质根节点左侧添加一个GeneratedRoundRect节点。
如果你将其连接到材质根节点,可以在预览窗口中看到节点输出的示例。
添加一个ScreenPosition节点。
将ScreenPosition节点的ViewportUV输出连接到GeneratedRoundRect节点的UVCoords (V2)输入。
ViewportUV输出会让GeneratedRoundRect节点在与视口屏幕坐标相同的空间中绘制遮罩。
要使用向量参数控制遮罩形状,请执行以下操作:
添加一个Constant4Vector节点。 你可以使用这个节点来创建一个颜色值,也可以更广泛地将它作为一组参数,用于控制GeneratedRoundRect遮罩的大小和形状。
按住键盘上的4,然后在图表中单击以添加该节点。
右键单击向量节点并选择Convert to Parameter以将常量转换为向量参数。 将其命名为
Damage Mask Controls。使用向量参数时,你可以像使用单值Constant(或Scalar Parameter)节点一样使用每个通道的值,使图表更加高效和整洁。 默认情况下,这些值带有RGBA颜色通道标签,但你可以在节点的细节面板中重命名,使这些值表示任何你想要的含义。
在细节面板中,展开Parameter Customization分类下的Channel Names,为向量参数节点中的每个颜色通道分配名称。 你将为这些通道命名以对应GeneratedRoundRect节点的输入:
R =
Size XG =
Size YB =
Corner RadiusA =
Sharpness
在Material Expression Vector Parameter分类中,展开Default Value,为每个通道设置以下默认值:
Size X = 1
Size Y = 1
Corner Radius = 0.4
Sharpness = 0.2
在材质图表中,从常量向量节点的Size X引脚拖出,创建一个AppendVector节点。
将Size Y引脚连接到Append节点的B输入。
将Append节点的输出引脚连接到GeneratedRoundRect节点上的Box Dimensions引脚。
连接Damage Mask Controls节点和GeneratedRoundRect节点上的Corner Radius和Sharpness引脚。
为这些节点添加一个注释框,并标注为
Damage Mask Falloff。
在GeneratedRoundRectNode中,UV Coords定义了材质绘制矩形的位置,而Box Dimensions定义了矩形在该空间内的大小。 当Box Dimensions设置为(1, 1)时,矩形(白色区域)会占据大部分屏幕空间;设置为(0.5, 0.5)时,矩形会占据屏幕宽度和高度的一半。
要查看矩形遮罩,请执行以下操作:
将GeneratedRoundRect节点连接到材质根节点的Emissive Color输入。
选择Damage Mask Controls节点,尝试不同的Size、Corner Radius和Sharpness值,观察它们对矩形产生的效果。
将数值重置为之前设置的默认值,并删除GeneratedRoundRect与主材质节点之间的连线。
在遮罩的不同部分显示视觉效果
在扩展材质实例教程中,你使用了线性插值(lerp)在石头地板材质的干湿效果之间进行混合。 地板的材质Lerp节点曾使用时间轴作为Alpha输入,在两个参数值之间进行混合。 请记住,在Lerp节点中,Alpha输入控制在A和B输入之间的混合程度。 当Alpha为0时,输出为全A。 当Alpha为1时,输出为全B。
Alpha值也可以来自灰度遮罩,其中每个像素提供一个值:白色区域显示B,黑色区域显示A,灰色区域则是两者的混合。 因此,在本节中,你将使用Lerp节点在屏幕中央(遮罩为白色处)未被遮挡的游戏画面与屏幕边缘(遮罩为黑色处)的红色之间进行混合。
要在游戏屏幕和代表受到伤害的红色之间进行混合,请执行以下操作:
在GeneratedRoundRect节点右侧添加一个LinearInterpolate(即Lerp)节点。 将鼠标悬停在节点上,点击Toggle Comment Bubble按钮,然后输入
1。为你的Lerp节点编号有助于你跟随教程执行操作,因为该图表中使用了多个Lerp节点。 我们将这个节点称为Lerp (1)。
将GeneratedRoundRect Result输出连接到Lerp (1)节点的Alpha输入。
添加一个SceneTexture节点。
在细节面板中,将Scene Texture Id更改为PostProcessInput0。
将SceneTexture节点的Color输出连接到Lerp (1)节点的B输入。
在图表中,添加一个Constant3Vector。 右键单击节点,选择转换为参数。 将该参数命名为
Damage Color。 该参数用于控制伤害效果的颜色。点击Default Value旁边的色条,将颜色更改为红色(R = 1)。
将Damage Color节点顶部(白色)的引脚连接到Lerp (1)节点的A输入端。 伤害颜色的顶部引脚仅输出RGB三个颜色通道。
将Lerp (1)的输出连接到材质根节点的Emissive Color引脚,以在预览窗口中查看效果。 你会看到一个由Float3到Float4转换问题导致的未定义算术错误。
Damage Color节点的顶部引脚输出一个Float3值(三个通道:RGB),而SceneTexture节点的Color引脚输出一个Float4值(四个通道:RGBA)。 要解决此错误并使值类型匹配,你可以使用Component Mask,从Scene Texture的Color输出中移除Alpha通道,因为你只需要三个通道(RGB)来匹配。 组件遮罩是解决此类错误的常用方法。
要将SceneTexture节点的颜色转换为Float3值并解决错误,请执行以下操作:
添加一个ComponentMask节点,将SceneTexture节点的Color引脚连接到Mask节点。
将Mask节点的输出连接到Lerp (1)节点的B输入。
点击Mask节点底部的箭头,查看颜色输出中每个通道的复选框。
默认情况下,组件遮罩仅遮罩R和G通道。 在B旁添加勾选标记。 这将创建一个Float3组件遮罩,以便两个Lerp (1)输入使用相同的通道。
此时的图表应如下所示:
在预览视口中,材质效果应如下所示:
为效果添加噪点和变化
在本节中,你将通过在框架外边缘应用纹理来构建材质的噪点部分。 至此,你可以使用材质参数来指导效果的最终外观,使其与游戏中角色的伤害相关联。
在视觉效果中,噪点可用于添加可控的随机性。 你可以使用这种模式使材质感觉更自然、不那么完美,例如用于不平坦的表面或闪烁的灯光。
要为材质添加噪点,请执行以下操作:
在图表底部,添加一个ScreenAlignedUVs节点。 使用ScreenAlignedUVs节点,你可以将纹理或效果映射到整个屏幕。 它会为整个视口或屏幕生成UV坐标。
从X 100%, Y 100%引脚拖出并添加一个Multiply节点。
右键单击并创建一个Constant节点。 右键单击它,选择Convert to Parameter,并将其命名为Noise Tiling。 将其连接到Multiply节点的B输入。
在Noise Tiling节点中,将Default Value设置为
1。从Multiply节点的输出引脚拖出连线,创建一个TextureSample节点,并将连线连接到其UVs输入。
右键单击TextureSample,将其转换为参数,并将其命名为
Noise Texture。选中Noise Texture节点,在细节面板底部的Material Expression Texture Base分类中,将Noise Texture纹理指定为
TilingNoise05。该纹理是虚幻引擎自带的引擎内容的一部分。 你可以使用自己的设置,但如果没有其他选项,不妨将此默认值作为起点。 注意:如果你使用不同的纹理,其效果可能与本教程展示的结果不同。
从Noise Texture节点的R通道拖出并创建一个Multiply节点。
右键单击其B引脚并选择Promote to Parameter。 将该参数命名为
Noise Falloff,并将其Default Value设置为1。从Multiply节点的输出引脚拖出并创建一个Power节点。
右键单击Exp引脚并选择Promote to Parameter。 将参数命名为
Noise Amount,并将其Default Value设置为1。选中你刚创建的八个节点,按C键为它们添加一个注释框。 将注释框标记为
Noise in Damage Mask。
此时,你可以通过将Power节点直接连接到M_Screen_Damage材质根节点上的Emissive Color输入来测试这部分材质的效果。 你应该在预览窗口中看到以下内容:
测试完成后,断开材质根节点与噪点纹理逻辑的连接,并将其重新连接到Lerp (1)节点。 在连接所有内容之前,你将继续构建材质的其他部分。
为遮罩添加噪点
现在你已经创建了噪点遮罩,需要通过一个Multiply节点将它与伤害遮罩的衰减效果相融合。 这会将噪点遮罩应用到靠近屏幕中心的伤害遮罩内边缘结果上。
要将噪点纹理添加到遮罩的黑色区域,请执行以下操作:
将
M_Screen_Damage材质根节点向右移动,以便在它与GeneratedRoundRect节点之间腾出空间。 删除GeneratedRoundRect节点和现有Lerp (1)节点之间的连线,因为你将在此处添加新的逻辑。右键单击图表并创建一个新的Lerp节点。 将鼠标悬停在节点上,点击Toggle Comment Bubble,并输入
2作为注释。将GenerateRoundRect节点的Result引脚连接到Lerp (2) 节点的Alpha引脚。
从GenerateRoundRect节点的output拖出连线,创建一个One Minus节点。
从One Minus节点拖出连线,创建一个Add节点,并将其输出连接到Lerp (2)节点的B引脚。
从One Minus节点拖出,添加一个Multiply节点。
从Multiply输出拖出,添加一个新的 One Minus节点,并将其连接到Add节点的B输入端。
在Lerp (2)之后,添加一个Saturate节点。 这会将输出值限制在0-1范围内。
给该逻辑添加一个注释,标记为
Gets the Brightest Spots of the Mask。
此时,你的材质应类似于这样:
连接噪点、遮罩和伤害颜色部分
要连接图表中的Noise、Damage Mask和Damage Color元素,请执行以下操作:
在噪点遮罩逻辑中,从Power节点拖出连线,连接到伤害遮罩区域逻辑中Multiply节点的B输入。
在任意连线上使用重路由节点来理清路径,并重新整理图表。 双击一条连线可添加一个重路由节点,然后拖动它以更改连线路径。
将Saturate节点的输出引脚连接到Lerp (1)节点的Alpha引脚。
保存和应用材质更改。
你可以将Lerp (1)节点连接到材质根节点上的Emissive Color输入以查看结果:
现在,你已经定义了一个矩形遮罩区域,为该遮罩应用了颜色,使用纹理创建了一个噪点遮罩,并将它们混合成当前在材质编辑器预览窗口中看到的效果。
为伤害效果添加脉动
在本节中,你将构建材质逻辑,这样在玩家受到更多伤害时,屏幕边缘的红色伤害指示器就会脉动。 你将使用一个Sine节点来驱动脉冲效果,并对正弦波进行调整,使其只使用正数值。
要使红色效果随着伤害增加而脉动,请执行以下操作:
在图表顶部的空白区域添加一个Time节点。
Time节点会在编辑器中输出时间流逝的数值,这对于为材质制作动画或在指定时间内改变材质效果非常有帮助。
从它的引脚拖出并添加一个Multiply节点。
创建一个Constant节点,将其转换为参数,并命名为Pulse Speed。 在该节点中,将其Default Value设置为
0.5。将Pulse Speed连接到Multiply节点的B输入端。
从Multiply节点拖出并添加一个Sine节点。
Sine节点会将不断增加的Time值转换为一个在-1到1之间平滑振荡的循环波形数值。
从Sine节点的输出引脚拖出连线,并添加一个Add节点。 确保其B输入值设置为1.0。
从Add节点拖出连线,添加一个Divide节点。 确保其B输入值为2.0。
设置Add 1再Divide 2,将正弦波更改为从1到0变化,而不是在1和-1之间变化。 这样可以防止Sine节点对纹理数值进行反转,避免画面从红色闪烁变成浅蓝色(红色的反相颜色)。
从Divide节点拖出并添加一个Multiply节点。
从其B输入拖出并创建一个Constant。 将其转换为参数并将其命名为
Pulse Amount。 将其Default Value设置为1。选择该图表部分中的节点,按C键添加一个注释框。 将其标记为
Damage Pulse Amount and Speed。
你的材质现在包含了构成此后期处理材质伤害效果的所有主要元素。 此时,你的图表应该与下图类似:
连接脉冲逻辑
现在你已经设置了脉冲逻辑,接下来将其集成到场景纹理的伤害颜色应用中。 然后,你可以调整遮罩脉动时的强度。
你将基于Damage Pulse Amount and Speed部分添加表达式,将脉动逻辑连接到图表中的Damage Color和Scene Texture部分。
在本节操作过程中,你将断开之前设置的一些元素,并整合新的连接关系。 在难以追踪重叠的连线时,可以拖动节点来腾出空间。
要将脉冲逻辑连接到伤害颜色,请执行以下操作:
在图表中右键单击,在Damage Color节点和脉冲逻辑附近创建一个新的Lerp节点。 将该节点标记为
3。在脉冲逻辑的末端,将Multiply节点的output连接到Lerp (3)的Alpha引脚。
在Lerp (3)节点中,Alpha用于控制应用到遮罩上的脉冲强度,以及脉冲发生的频率。
删除Lerp (1) 节点A输入端连接的Damage Color连线,并将其连接到新建的Lerp (3)节点的B输入端。
选择Damage Color节点。 在细节面板的Parameter Customization下,展开Channel Names,使用文本字段将A通道名称更改为
Color Amount。在Material Expressions Vector Parameter类别中,在Default Value下,将Color Amount值设置为
2。在Damage Color节点上,从Color Amount引脚拖出,添加一个Divide节点,并将其输出连接到Lerp (3)的A输入。
在Lerp (3)和脉冲逻辑附近创建一个新的Lerp节点。 用
4为其添加标签。将Lerp (3)节点的输出连接到Lerp (4)的Alpha输入。
将Damage Color节点的RGB(白色)引脚连接到Lerp (4)的B输入。
返回到连接至SceneTexture节点的Mask (RGB)节点。 将Mask节点的输出连接到Lerp (4)的A输入。 组件遮罩节点现在分别连接到Lerp (1)的B输入,以及Lerp (4)的A输入。
将Lerp (4)的输出连接到Lerp (1)的A输入。
拖动选择Lerp (3)和Lerp (4)节点。 按C为它们创建一个注释框,并标注为
Lerp Pulse and Color。点击保存和应用。
图表中新增加的这个部分应该如下图所示:
你可以将Lerp (3)连接到材质根节点的Emissive Color输入端口,以在材质预览窗口中查看伤害效果:
在上面的示例中,Damage Color节点的Color Amount值被调高到5.0,以便在预览窗口中清晰地看到效果。
在图表中,更改Pulse Speed和Pulse Amount的值,观察它们如何改变效果的大小以及效果应用的速度。 脉冲强度必须在0到1之间。 在后续步骤中,你可以在材质实例中控制这两个参数。
使用Damage Amount参数控制效果
你需要在材质图表中添加的最后一个内容是名为Damage Amount的新参数,它会根据玩家在游戏中受到的伤害程度来控制效果的大小。
该参数将在角色的蓝图中进行设置:当玩家受到伤害时,该参数会控制屏幕边缘显示的脉冲伤害效果强度。 玩家受到的伤害越多,该材质在玩家屏幕上的效果就越强。
要添加一个在运行时控制效果大小的参数,请执行以下操作:
在你现有的材质逻辑和
M_Screen_Damage材质根节点之间添加一些空间。 右键单击图表并添加一个Lerp节点。 将该Lerp节点标记为5。将Mask (RGB)节点的输出连接到Lerp (5)节点的A引脚。
将Lerp (1)节点的输出连接到Lerp (5)的B输入。
在Lerp (5)上,右键点击Alpha引脚,选择Promote to Parameter,将参数命名为Damage Amount,并将默认值改为
1。准确地为该参数命名,并确保它有默认值;当玩家受伤或恢复生命时,玩家角色蓝图将使用此参数控制该材质在屏幕上显示的程度。
将Lerp (5)节点的输出连接到根节点的Emissive Color输入。
Damage Amount值使用一个介于0(无伤害,效果关闭)和1(最大伤害,效果开启)之间的数值。
这是你将在预览窗口中看到的结果:
在这里的示例中,Damage Color节点的Color Amount值被调高到5.0,以便在预览窗口中清晰地看到效果。
接下来,你将添加一组新的节点,使用Damage Amount作为输入来影响GeneratedRoundRect遮罩的大小。 此添加使伤害效果随着玩家受到更多伤害而向屏幕中心向内脉动,并随着玩家生命值恢复而退缩。
要让Damage Amount影响伤害遮罩的大小和强度,请执行以下操作:
在材质图表中,前往Damage Mask Falloff部分。 删除Append节点和GeneratedRoundRect节点之间的连线。
从Append节点拖出并添加一个Multiply节点。
将Multiply节点的输出连接到GeneratedRoundRect节点的Box Dimensions输入。
在Multiply节点上,从输入B拖出连线并添加一个Lerp节点。 将Lerp节点标记为
6。在Lerp (6)节点上,保持A值为0,并将B值设置为
0.75。右键单击Lerp (6)节点的Alpha,选择提升为参数。 将该节点命名为Damage Amount,以同另一个Damage Amount节点保持一致。 你也可以复制并粘贴原始的Damage Amount节点。
点击应用和保存。
这是你将在预览窗口中看到的结果:
在这里的示例中,Damage Color节点的Color Amount值被调高到5.0,以便在预览窗口中清晰地看到效果。
当所有内容构建完成后,你的M_Screen_Damage材质图表应如下所示:
要将此代码片段复制到你的项目中,请删除材质图中所有现有节点,点击Copy Full Snippet,然后在你的材质中按Ctrl + V进行粘贴。 然后,将Lerp (5)节点连接到主材质节点的Emissive Color引脚。
创建材质实例以控制效果
现在你已经有了材质,创建一个材质实例来控制你在材质中创建的所有参数。 你将使用材质实例中公开的参数来定义屏幕上的伤害效果的最终外观和表现。
要设置材质实例以控制材质参数,请执行以下操作:
在内容浏览器中,在你的Artist > Materials文件夹里,右键单击材质
M_Screen_Damage,然后从上下文菜单中选择Create Material Instance。将资产命名为
MI_Screen_Damage并打开它。为了让材质预览实时运行,并查看参数变化对材质的影响,点击视口上方的黄色秒表按钮两次。
在细节面板中,展开Parameter Groups下的各个部分,查看你在材质中公开的所有参数。 展开向量参数(例如Damage Mask Controls),即可查看各个独立通道的参数数值。
为除Noise Texture之外的所有参数勾选复选框,使其可以被重载。
在更改参数值后取消选中该参数,使用父材质中设置的原始默认值。
在编辑材质实例时,可以尝试调整不同的参数,观察它们在预览窗口中对伤害效果的影响。 尝试不同的Pulse Amount、Noise Falloff、Pulse Speed以及Damage Mask Controls(向量参数)数值,观察它们如何改变效果。
伤害量的默认值设置为1,因此你可以在预览窗口中看到材质发生的变化。 不过,请将该值改为
0,这样在游戏开始时,该效果就不会立即出现在屏幕上,而是在玩家受到伤害后才显示。 在下一节中,你将让玩家角色蓝图控制该值。保存该材质实例。
稍后,当你能够在游戏中测试效果时,可以返回材质实例,重复这些步骤来调整效果。
在材质实例中设置参数值
本教程示例关卡使用了以下参数值。 你可以使用这些值,或根据项目需要进行调整。
参数 | 默认值 | 建议值 |
全局标量参数值 | ||
伤害量 | 0 | 0 |
噪点强度 | 1.0 | 0.35 |
噪点衰减 | 1.0 | 0.75 |
噪点平铺 | 1.0 | 1.1 |
脉冲强度 | 1.0 | 0.75 |
脉冲速度 | 0.5 | 0.65 |
全局纹理参数值 | ||
噪点纹理 | TilingNoise05 | TilingNoise05 |
全局向量参数值 | ||
伤害颜色 | Hex sRGB: FF0000FF | Hex sRGB: FF0000FF |
伤害颜色:颜色强度 | 2.0 | 5.0 |
伤害遮罩控制:Size X | 1.0 | 0.75 |
伤害遮罩控制:Size Y | 1.0 | 0.5 |
伤害遮罩控制:Corner Radius | 0.4 | 2.0 |
伤害遮罩控制:Sharpness | 0.2 | 2.1 |
[可选]整理并限制参数值
为了使材质实例的参数值更易于浏览和使用,并减少极端值的出现,你可以将参数分组,并应用值范围,将数值滑块保持在可接受或预期的值范围内。
例如,Damage Amount用于映射玩家的生命值状态:0表示屏幕无伤害效果,1表示屏幕满伤害效果。因此,为该参数设置一个0到1范围的滑动条是合理的,因为它不可能超出这个范围。
在父材质中,选中每一个已命名的参数,并在细节面板中为它们分别设置Group、Slider Min和Slider Max范围,如下所示:
参数 | 组 | 滑条最小值 | 滑条最大值 |
伤害量 | 伤害(Damage) | 0 | 1 |
脉冲强度 | 脉冲 | 0 | 1 |
脉冲速度 | 脉冲 | 0 | 2 |
伤害颜色:颜色强度 | 脉冲 | 不适用 | 不适用 |
噪点平铺 | 噪点 | -1 | 2 |
噪点衰减 | 噪点 | 1 | 5 |
噪点强度 | 噪点 | 0.5 | 3 |
伤害遮罩控制 | 噪点 | 不适用 | 不适用 |
噪点纹理 | 噪点 | 不适用 | 不适用 |
在材质实例中,你可以在参数列表中看到此更改对该值的影响。 参数根据其分组被整理到新的类别中。 你可以在最小值和最大值之间拖动滑块,而不会超出这个范围。不过,你也可以通过手动输入新数值来重载滑块的限制。
将后期处理材质添加到角色蓝图
现在,你已经设置并实例化了后期处理材质。 接下来,你将设置角色蓝图,以创建并使用一个Dynamic Material Instance(也称为Material Instance Dynamic,简称MID)。 这将使用MI_Screen_Damage材质实例在蓝图中读取名为Damage Amount的参数。 使用你在蓝图图表中设置的逻辑,你可以在游戏过程中将值注入到材质实例的Damage Amount参数中,从而根据游戏中发生的情况实时调整材质效果。
角色拥有一个Health变量,在受到伤害时会发生变化。 你将结合使用该变量与材质实例,在角色受到更多伤害时,将该效果应用到屏幕上,并在生命值恢复时移除该效果。
创建动态材质实例并将其添加到后期处理中
你的材质实例是无法在运行时直接修改的资产。 不过,你将在角色蓝图中创建一个动态材质实例。 动态材质实例是在游戏运行时创建的材质实例版本,你可以在游戏运行过程中通过其命名参数进行修改。 然后,你将把MID分配给玩家的摄像机,以便在玩家受到伤害时让它显示在屏幕上。
要在变量中创建并保存该材质实例,请执行以下操作:
在内容浏览器中,进入Content > AdventureGame > Designer > Blueprints > Characters,并打开
BP_AdventureCharacter蓝图。在事件图表中,找到以Event BeginPlay节点开头的逻辑组。 将该逻辑组拖动到图表中更空旷的区域,以便为后续添加更多节点预留空间。
要在图表中查找事件节点,请在My Blueprint面板中展开EventGraph列表,然后双击Event BeginPlay。 图表视图聚焦在该节点上。
在Set Default Movement Speed节点之后,从执行(exec)引脚拖出,添加一个Create Dynamic Material Instance节点。
在该Create Dynamic Material Instance节点上,将Parent设置为
MI_ScreenDamage。 这是你之前创建的材质实例,用于控制屏幕上的伤害效果。右键单击节点的Return Value引脚并选择提升为变量。
在My Blueprint面板的Variables列表中,将NewVar重命名为
MID Damage。
现在,Create Dynamic Material Instance节点会创建MI_Screen_Damage的运行时版本,并将其保存到新变量中,使其可以在图表的其他位置引用。
要将材质实例分配给摄像机的后期处理通道,请执行以下操作:
在组件面板中,将FirstPersonCamera组件拖到图表中。 这会创建一个对玩家摄像机的引用。
从其输出端拖出并创建一个Set Post Process Settings节点。
连接两个Set节点的exec引脚。
从Set Post Process Settings节点的Post Process Settings输入端拖出,添加一个Make Post Process Settings节点。
选择Make Post Process Settings节点。 在Detail面板的Rendering Features分类中,勾选Post Process Materials,以便将该引脚添加到Make Post Process Settings节点。
在节点中,右键单击Post Process Materials输入引脚并选择Split Struct Pin。 该引脚现在接收一个数组作为输入。
从Post Process Materials Array引脚拖出,添加一个Make Array节点。
从Make Array节点的[0]输入拖出,添加一个Make Weighted Blendable节点。
在Make Weighted Blendable节点上,将Weight更改为
1。从Set MID Damage节点的输出(蓝色)引脚拖出连线,连接到Make Weighted Blendable节点Object输入。
Set节点的输出引脚会返回该变量的引用。
选中你在图表中添加的节点,按C键为它们创建一个注释框。 为其添加标签:
Create Dynamic Material Instance for Post-Process Effect and assign to Player Camera。编译并保存此蓝图。
此逻辑会在游戏开始时创建动态材质实例,并将其应用到该蓝图的第一人称摄像机上。
玩家Event BeginPlay逻辑新增的部分如下所示:
以下是一段上面高亮部分的代码片段,你可以将它复制到事件图表中,而无需自己构建逻辑:
在游戏中测试效果
在材质实例(MI_Screen_Damage)中,临时将Damage Amount更改为1,然后单击Save。 运行游戏后,你可以在角色未受到伤害的情况下测试该效果,以便调整到理想的视觉表现。 当Damage Amount设置为1时,材质将持续开启。 当你完成材质测试后,将Damage Amount重置为0。
接下来,你将向角色蓝图添加逻辑,使该动态材质实例在角色受到伤害时出现,并在生命值恢复时逐渐减弱。
根据受到的伤害显示或隐藏效果
为了让动态材质实例效果仅在玩家受伤时出现,你需要在玩家角色中扩展现有的伤害处理逻辑。
这个新的逻辑需要实现以下功能:
根据角色的Health变量调整材质的Damage Amount参数,使其满足以下逻辑:
当Health为满值时,屏幕上不会出现后期处理效果。
当Health减少时,屏幕上的后期处理效果会逐渐增强。
当玩家在一段时间内未再受到伤害时,将Health恢复为满值,并移除后期处理效果。
创建Maximum Health变量
你将使用玩家的生命值,因此最好将玩家的最大生命值保存在一个变量中,以便在整个伤害效果逻辑中引用,而不是直接输入静态的硬编码值100。 这样,如果你决定调整角色的初始生命值(无论增加还是减少),你的蓝图逻辑仍然能够正常运行。
要创建一个用于存储玩家最大生命值的变量,请执行以下操作:
在
BP_AdventureCharacter中,在My Blueprint面板的Variables部分,点击+添加一个新变量。将其命名为
MaxHealth,并将类型更改为Float。 编译此蓝图。在事件图表中,关注上一节中处理的Event BeginPlay逻辑组中的Event BeginPlay和Set Default Movement Speed节点。
从Event BeginPlay拖出并添加一个Set MaxHealth节点。
从Variables列表中,将Health变量拖到新的Set节点的Max Health引脚上。
现在,当游戏开始时,Health的默认值(100)会被保存到MaxHealth。 随着玩家游戏过程中Health的变化,MaxHealth保持不变,保证玩家的最大血量不受影响。
将当前玩家生命值连接到材质
首先,你将扩展玩家的伤害处理逻辑,使用伤害量(Damage Amount)参数来控制动态材质实例,这样当玩家生命值降低时,屏幕上的效果强度便会随之增强。
要随着玩家生命值损失而放大伤害量,请执行以下操作:
在角色蓝图中,前往事件图表左下角标记为(DT) 伤害与失败处理的逻辑组。 你将要在Set Health和Branch节点之间添加新的逻辑,因此请在这两个节点之间预留一些空间。
在Variables列表中,将MID Damage变量拖到图表上,并选择Get MID Damage。
从Get MID Damage节点的输出引脚拖出连线,在列表中选择Set Scalar Parameter Value。
将Set Health连接到Set Scalar Parameter Value,然后再连接到Branch节点。
在Set Scalar Parameter Value节点中,将Parameter Name设置为
Damage Amount。 这是控制屏幕上效果大小和强度的材质参数。此名称必须与材质
M_Screen_Damage中的相应参数匹配,效果才能生效。在Set Scalar Parameter Value节点上,从Value输入引脚拖出并创建一个Lerp节点。
在Lerp节点上,将A设置为
1.0,将B设置为0。 这样会重新映射数值,这样在受到伤害时,角色的生命值就会从最大值(100)递减到0,而不是反过来。在Lerp节点上,从Alpha输入引脚拖出连线,创建一个Divide节点。
在Variables列表中,将角色的Health变量拖到Divide节点的顶端输入端口。
将角色的MaxHealth变量拖到Divide节点的下方输入端。
Divide节点将玩家的生命值转换为0到1之间的数值,其中1代表满血(无伤害)。 但是,Damage Amount的值应该随着玩家生命值的减少而增加,而不是减少。 Lerp节点会反转数值范围。 例如,如果Health为 25,Lerp会向Set Scalar Parameter Value节点返回0.75,这会产生达到最大强度75%的效果。
现在,图表中的 (DT) 伤害与失败处理部分应类似如下所示:
添加重置延迟以恢复生命值
为了让玩家的Health(或HP)恢复到满值并使伤害效果消失,应让玩家角色在短时间内停止受到伤害。 你将使用一个Retrigerable Delay节点来实现一个5秒的延迟,只有延迟完成后,Health才会恢复。这种延迟节点可以用于重置冷却时间:它会等待设定的时间结束后再执行下一个节点;如果在时间结束前再次被触发,它会重新开始倒计时。
要在移除伤害效果之前添加一个延迟,请执行以下操作:
在Branch节点下,从Fn Set HP节点的exec引脚拖出,添加一个Sequence节点。 你将使用它来添加一系列在玩家受到伤害(但尚未死亡)之后执行的操作。
从Then 0路径拖出并添加一个Retriggerable Delay节点。 在延迟节点中,将Duration设置为
5秒。最佳做法是在延迟后检查玩家是否还活着:
从Retriggerable Delay拖出并添加一个Branch节点。
在Branch节点上,从Condition引脚拖出,添加一个Greater (>)节点。
在Variables面板中,将Health变量拖到Greater (>)节点的上方输入引脚。
现在,每当玩家受到伤害且未被淘汰(生命值不为0)时,时间延迟都会从0重新开始。 接下来,你将设置延迟完成后应执行的逻辑。
此时,你的蓝图图表应该与下图类似:
使用时间轴混合玩家生命值
在图表的这个部分中,你将添加一个时间轴,用于在短时间内逐渐恢复玩家的Health。 时间轴节点的控件定义了它如何开始、停止,以及在轨道时间内的行为。
要设置一个持续五秒的时间轴,请执行以下操作:
在图表的Sequence节点的Then 0逻辑下方,右键单击图表,在节点操作列表中搜索
add timeline,然后选择Add Timeline。 将时间轴节点命名为Damage Blend。双击Damage Blend节点,在蓝图中将它打开为单独的选项卡。
在此选项卡中,单击+ 轨道 > 添加浮点轨道以向时间轴添加一个新轨道。
将轨道命名为Blend。 该轨道标签也会作为一个输出引脚出现在 伤害混合时间轴节点。
在+ Track按钮旁,确保Length设置为5秒。
在Blend曲线中,右键单击并选择Add key to CurveFloat_0。 重复此操作以添加另一个关键帧——总共需要两个。
点击第一个关键帧,将其数值设置为:Time = 0,Value = 0。
点击第二个关键帧,将其值更改为Time = 5和Value = 1。
右键点击第一个关键帧,选择Auto。 这会将混合方法从线性混合改为在0到1之间进行平滑过渡。
使用蓝图选项卡,切换回包含Damage Blend Timeline节点的Event Graph。
在Sequence节点上,将Then 1执行引脚连接到 Damage Blend节点的Stop引脚。
在延迟后的Branch节点中,从True引脚拖出,并连接到Damage Blend节点的Play from Start输入端。
现在,此时间轴节点输出一个在五秒内从0到1变化的值。 当Retriggerable Delay完成时,时间轴就会开始播放。 当时间轴轨道逻辑完成时,程序会顺着Then 1这条线继续往下执行,并且停止时间轴的更新。
恢复玩家生命值并移除后期处理材质
现在你已经设置好了时间轴,接下来将构建逻辑,使用这个五秒的轨道将玩家的Health变量混合回其初始满值,并将材质的Damage Amount降低回 0。
要使用时间轴逐步恢复玩家生命值,请执行以下操作:
在Damage Blend Timeline节点之后,创建一个Lerp节点。 将时间轴的Blend输出引脚连接到Lerp节点的Alpha输入引脚。
在Lerp节点上,从B输入拖出连线,添加一个对MaxHealth的引用。
在Variables列表中,将Health变量拖放到Lerp节点的A输入上。
从Lerp节点的Return Value引脚拖出连线,添加一个Set Health节点(在节点操作列表的Variables > Default下)。
从时间轴的Update引脚拖出并连接到Set Health节点的exec引脚。
现在,Lerp节点在五秒内(时间轴的长度)将玩家的当前Health值混合到他们在游戏开始时拥有的最大生命值(在此例中为100)。
返回到事件图表中包含你在Branch节点之前创建的Set Scalar Parameter Value节点的部分。 框选Set Scalar Parameter Value、MID Damage、Lerp、Divide和Health节点,然后按Ctrl+C进行复制。
在事件图表中,返回到Damage Blend时间轴,然后按Ctrl+V粘贴节点。
将Set Health节点的exec引脚连接到Set Scalar Parameter Value的exec引脚。
现在,随着玩家的Health变量恢复到满值,Damage Amount会相应地降回0。
此时,你的图表应该与下图类似:
在HUD上显示更新的生命值
当Health变量逐渐恢复到100时,玩家UI上显示的值会带有两位小数。 为了从HUD中移除这种视觉噪点,你需要添加去除小数位的逻辑,仅以整数形式显示Health。
这是一个示例,展示了使用截断(Truncate)去除小数位的差异。
为了确保在HUD上显示的玩家Health为整数,请执行以下操作:
转到在你创建的Sequence节点之前执行的Fn Set HP节点。 选择Fn Set HP节点及其输入(HUD和Health),按Ctrl + C进行复制。
在时间轴逻辑末尾的Set Scalar Parameter Value节点之后,按Ctrl + V粘贴这三个节点。
连接Set Scalar Parameter Value节点和Fn Set HP节点的exec引脚。
将Fn Set HP节点向右拖动,以便腾出一些空间。
删除Health变量和Fn Set HP节点上的New HP输入之间的连线。
从Health变量拖出连线,添加一个Truncate节点。 这会将浮点值转换为整数,移除小数部分。
从Truncate节点拖出,并将其连接到Fn Set HP节点的New HP输入端。 虚幻引擎会自动添加一个整数到浮点的转换节点。
编译并保存此蓝图。
现在,包含所有新增内容后的完整蓝图应如下所示:
测试最终效果
现在当你进行游戏并受到伤害时,你应该会看到后期处理伤害效果出现,并随着你承受更多伤害而增强。
你可以返回材质实例,调整参数值,以获得最终想要的效果。 以下示例展示了被放大的伤害效果。
下一步
在下一节中,你将学习通过在低洼区域添加更浓的雾气、在天空中加入暴风云层,来增强关卡的氛围效果。