斯坦福UE4 + C++课程学习记录 16:材质-闪烁溶解效果

目录

1. 创建材质

2. 代码传值

3. 溶解效果


        这节将实现一个物体受击后的闪烁特效。

1. 创建材质

        首先,在Materials文件夹下创建一个新的材质M_HitFlashDemo,设置任意基础颜色。课程中使用了一个很巧妙的办法设置“自发光颜色”属性,从而实现材质瞬间的闪烁。如图16-1所示,在材质中拥有一个时间,当物体被Hit时,通过C++把TimeToHit设置为当前时间,在这个瞬间两者相减的结果为0;但Hit触发时需要物体发光,“自发光颜色”属性需要设置大于0,于是接通过1-x节点把0变为1。最后,由于材质内的Time节点会持续更新,导致减法的差值越来越大,使用Clamp限制其上下界为1和0。

图16-1 受击闪烁

        我们可以如图16-1所示,将Time节点的“材质表达式时间”的“结束”勾选并设置为3,这样就可以预览材质闪烁的效果:

图16-2 闪烁效果

2. 代码传值

        接下来,转入VS中利用C++中实现传入时间的逻辑,此时务必将Time节点的“结束”取消勾选

        首先,在UE中从Actor派生一个SurTargetDummy类,用于编写相关代码。这部分代码很简单,创建一个静态网格体组件和在第13节中实现的SurAttributeComp组件,并绑定其中自定义的OnHealthChanged事件,以实现设置TimeToHit变量为当前时间。

SurTargetDummy.h

#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SurTargetDummy.generated.h"

class USurAttributeComponent;

UCLASS()
class SURKEAUE_API ASurTargetDummy : public AActor
{
	GENERATED_BODY()
	
protected:

	UPROPERTY(VisibleAnywhere)
	USurAttributeComponent* AttributeComp;

	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* MeshComp;
	
	UFUNCTION()
	void OnHealthChanged(AActor* InstigatorActor, USurAttributeComponent* OwningComp, float NewHealth, float Delta);

public:	
	ASurTargetDummy();
};

SurTargetDummy.cpp

#include "SurTargetDummy.h"
#include "SurAttributeComponent.h"

ASurTargetDummy::ASurTargetDummy()
{
	MeshComp = CreateDefaultSubobject<UStaticMeshComponent>("MeshComp");
	RootComponent = MeshComp;

	AttributeComp = CreateDefaultSubobject<USurAttributeComponent>("AttributeComp");
	AttributeComp->OnHealthChanged.AddDynamic(this, &ASurTargetDummy::OnHealthChanged);
}

void ASurTargetDummy::OnHealthChanged(AActor* InstigatorActor, USurAttributeComponent* OwningComp, float NewHealth, float Delta)
{
	// 治愈(>0)或免疫(=0)时不触发受击特效
	if (Delta < 0) {
		MeshComp->SetScalarParameterValueOnMaterials("TimeToHit", GetWorld()->TimeSeconds);
	}
}

        随后回到UE,在Content下创建TargetDummyBP蓝图类,继承上面的TargetDummy类。为其设置任意一个几何体,并设置我们的闪烁材质M_HitFlashDemo。将其放置在场景中并运行:

图16-3 运行测试

        可以看见此时的闪烁速度还是比较慢的,如果希望加快闪烁的速度,只需要增加“自发光颜色”值的变化速度,所以在减法后加入乘法,乘数可自行调整:

图16-4 增加乘法
图16-5 增加速度

        进一步,我们可以将乘法的乘数作为一个参数暴露出来,将其创建为HitFlashSpeed参数,并设置默认值不为0。这样做之后,我们可以像上一节一样创建材质实例,方便实时调整动画速度;更进一步,我们还可以在代码中实现根据伤害量决定闪烁的速度的功能 ,或者任何其他你能想到的效果。


3. 溶解效果

        我们将使用类似的方法,再创建一个名为M_DissolveEffect的具有溶解效果的材质。首先,在细节面板中将该材质的“混合模式”设置为“遮罩”(一个通用概念,像一个罩子一样放在原物体上,控制其是否显示),为了材质透明后可以渲染另一边的内容,可以勾选“双面”。

        创建一个Texture Sample,设置为任意一个名字带有“cloud”或“noise”的纹理,我这里设置的是Gideon文件中的T_TilingClouds_01。随后,将其连入“不透明蒙版”引脚, 这样,就可以看到部分透明的效果:

图16-6 蓝图设置
图16-7 部分透明效果

        为了稍后可以正常显示动态的溶解效果,记得如上图那样勾选“实时”。

        现在,我们可以尝试调整材质的“不透明蒙版剪切值”来观察对显示效果的影响,可以发现这个值越大、材质透明的部分越多。根据课程的介绍,我们使用的纹理各个点的Alpha值不等(决定是否透明的通道),“不透明蒙版剪切值”就是决定显示与否的阈值,纹理的Alpha值超过这个阈值的部分就可以显示。因此,我们可以通过设置Alpha值来控制动态的溶解效果:

图16-8 溶解效果

        将Time节点设置1的周期,“不透明蒙版剪切值”设置为1。如果大家不太理解上面的原理,可以分析一下每个节点的取值,或者利用上一节学习的打印字符串的方法。保存后应用到场景中的正方体上查看效果:

图16-9 运行测试

猜你喜欢

转载自blog.csdn.net/surkea/article/details/127266725