UE5之实现技能冷却效果
1.材质
创建一个新材质M_ColdDown,蓝图节点:

然后将细节面板的材质域修改为用户界面,将节点连到最终颜色用做UI显示:

2.控件
右键 用户界面---控件蓝图 创建一个蓝图控件用做UI显示,注意这里变量的名字:

创建一个C++类继承自 UUserWidget,这里是实际逻辑实现的地方。创建完成之后,将控件蓝图的父类指定为刚刚创建的C++类(图表---类设置---父类):


OK,现在新创建的类中什么也没有,先添加一个构造函数,注意这个函数只有在控件被添加到视口的时候才会调用:
public: virtual void NativeConstruct() override;
这里因为刚刚已经设置好了父类,因此可以使用 BindWidget 绑定蓝图控件中的变量,注意变量名必须于蓝图控件中的变量名一致。同时创建一个动态材质实例用于图像的材质:
UPROPERTY(meta = (BindWidget)) UImage* FireImage; UPROPERTY(meta = (BindWidget)) UButton* FireButton; UPROPERTY() UMaterialInstanceDynamic* DynamicMaterial; // 动态材质实例
然后在构造函数中进行初始化,同时绑定Button的点击事件:
void UBoilerWidget::NativeConstruct() { Super::NativeConstruct(); // 绑定点击事件 FireButton->OnClicked.AddDynamic(this, &UBoilerWidget::OnFireImageClicked); // 加载材质 UMaterialInterface* BaseMaterial = LoadObject<UMaterialInterface>(nullptr,TEXT("/Game/_project/Materials/M_ColdDown")); DynamicMaterial = UMaterialInstanceDynamic::Create(BaseMaterial, this); DynamicMaterial->SetScalarParameterValue("color", 0.05f); DynamicMaterial->SetScalarParameterValue("percentage", 0.0f); FireImage->SetBrushFromMaterial(DynamicMaterial); }
3.冷却效果的实现
这里我们需要一个 Timer 计时器用来实现冷却的效果,比如在5秒内不断让进度条更新。C++中实现定时器首先我们需要一个计时器句柄 TimerHandle 用来进行管理:
float CurrentPercentage; FTimerHandle TimerHandle; // 计时器句柄
然后在 button 的点击函数中启动计时器:
void UBoilerWidget::OnFireImageClicked() { CurrentPercentage = 1.0f; // 启动插值计时器 GetWorld()->GetTimerManager().ClearTimer(TimerHandle); GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &UBoilerWidget::UpdateMaterialPercentage, 0.05f,true); } void UBoilerWidget::UpdateMaterialPercentage() { if (CurrentPercentage > 0.0f) { // 计算插值(5秒内从 1 → 0) CurrentPercentage = FMath::FInterpConstantTo(CurrentPercentage, 0.0f, 0.05f, 1.0f / 5.0f); DynamicMaterial->SetScalarParameterValue("percentage", CurrentPercentage); FireImage->SetBrushFromMaterial(DynamicMaterial); } else { // 停止计时器 GetWorld()->GetTimerManager().SetTimer(TimerHandle,[this]() { GetWorld()->GetTimerManager().ClearTimer(TimerHandle); },5.0f,false); } }
注意这里 UpdateMaterialPercentage() 是一个C++的委托,也就是说不能带任何参数。并且由于控件是继承自UUserWidget,属于UI系统,因此不能直接使用GetWorldTimerManager()设置计时器。
4.添加到视口
在需要使用的地方,比如某个Actor中,创建该控件类的对象:
UPROPERTY(EditAnywhere) TSubclassOf<UUserWidget> TestClass; UPROPERTY() UBoilerWidget* BoilWidget;
并在构造函数中初始化控件蓝图的类:
static ConstructorHelpers::FClassFinder<UBoilerWidget> WidgetClass(TEXT("/Game/_project/Materials/Boiler/NewWidgetBlueprint")); if (WidgetClass.Succeeded()) { TestClass = WidgetClass.Class; }
最后显示即可:
BoilWidget = CreateWidget<UBoilerWidget>(GetWorld(), TestClass);
BoilWidget->AddToViewport();
5.效果

浙公网安备 33010602011771号