1.创建UserWidget类。
它的子类:class CRUNCH_API UValueGauge : public UCUserWidget
2.Source/Crunch/Crunch.Build.cs:
添加:
PrivateDependencyModuleNames.AddRange(new string[]
{
"GameplayAbilities",
"GameplayTasks",
"GameplayTags",
"UMG",
"Slate",
"SlateCore"
});
3.添加变量和方法:
Source/Crunch/Public/UI/Widget/ValueGauge.h:
// Copyright@ChenChao
#pragma once
#include "CoreMinimal.h"
#include "UI/Widget/CUserWidget.h"
#include "ValueGauge.generated.h"
class UTextBlock;
class UProgressBar;
/**
*
*/
UCLASS()
class CRUNCH_API UValueGauge : public UCUserWidget
{
GENERATED_BODY()
public:
//预构造
virtual void NativePreConstruct() override;
//修改值
void SetValue(float NewValue, float NewMaxValue);
private:
//进度条颜色
UPROPERTY(VisibleAnywhere, Category ="Visual")
FLinearColor BarColor;
//进度条
UPROPERTY(VisibleAnywhere, meta = (BindWidget))
TObjectPtr<UProgressBar> ProgressBar;
//文本框
UPROPERTY(VisibleAnywhere, meta = (BindWidget))
TObjectPtr<UTextBlock> ValueText;
};
Source/Crunch/Private/UI/Widget/ValueGauge.cpp:
// Copyright@ChenChao
#include "UI/Widget/ValueGauge.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
void UValueGauge::NativePreConstruct()
{
Super::NativePreConstruct();
ProgressBar->SetFillColorAndOpacity(BarColor); //进度条设置颜色
}
void UValueGauge::SetValue(float NewValue, float NewMaxValue)
{
if (NewMaxValue == 0)
{
UE_LOG(LogTemp, Warning, TEXT("Value Gauge: %s, 新的最大值不能是0."), *GetName());
return;
}
//设置进度条百分比
float NewPercent = NewValue / NewMaxValue;
ProgressBar->SetPercent(NewPercent);
//处理文本格式化:最大小数位为0
FNumberFormattingOptions FormattingOptions = FNumberFormattingOptions().SetMaximumIntegralDigits(0);
//设置文本框内容
ValueText->SetText(
FText::Format(//格式化文本
FTextFormat::FromString("{0}/{1}"),
FText::AsNumber(NewValue, &FormattingOptions),
FText::AsNumber(NewMaxValue, &FormattingOptions)
)
);
}
该代码实现了一个Unreal Engine的数值计量器控件,主要功能是通过进度条和文本来显示当前值与最大值的比例关系。以下是关键实现分析:
-
控件初始化
NativePreConstruct
方法中通过SetFillColorAndOpacity
设置了进度条的初始颜色,确保UI构建时即应用预设颜色。 -
数值安全处理
SetValue
方法包含对NewMaxValue=0
的防御性检查,避免除零错误并通过UE_LOG
输出警告日志。 -
UI同步更新
- 进度条使用
SetPercent
更新百分比显示 - 文本控件采用
FText::Format
实现"当前值/最大值"的格式化显示 - 通过
FNumberFormattingOptions
限制数值显示为整数
- 进度条使用
-
改进建议
- 可增加颜色渐变功能,根据百分比变化自动调整进度条颜色
- 建议添加数值变化动画效果提升用户体验
- 可扩展支持不同数值格式(如百分比模式)
该实现符合UE控件开发规范,通过BindWidget
绑定的控件需确保在UMG蓝图中存在同名元素。若需更复杂仪表盘功能,可参考面板仪表盘的绘制方法实现。
4。修改代码,增加颜色渐变功能,根据百分比变化自动调整进度条颜色
Source/Crunch/Public/UI/Widget/ValueGauge.h:
// Copyright@ChenChao
#pragma once
#include "CoreMinimal.h"
#include "UI/Widget/CUserWidget.h"
#include "ValueGauge.generated.h"
class UTextBlock;
class UProgressBar;
/**
*
*/
UCLASS()
class CRUNCH_API UValueGauge : public UCUserWidget
{
GENERATED_BODY()
public:
//预构造
virtual void NativePreConstruct() override;
//修改值
void SetValue(float NewValue, float NewMaxValue);
private:
//进度条颜色
UPROPERTY(VisibleAnywhere, Category ="Visual")
FLinearColor BarColor;
// 添加颜色渐变参数
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Visual",meta=(AllowPrivateAccess))
FLinearColor MinColor = FLinearColor::Red;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Visual",meta=(AllowPrivateAccess))
FLinearColor MaxColor = FLinearColor::Green;
//进度条
UPROPERTY(VisibleAnywhere, meta = (BindWidget))
TObjectPtr<UProgressBar> ProgressBar;
//文本框
UPROPERTY(VisibleAnywhere, meta = (BindWidget))
TObjectPtr<UTextBlock> ValueText;
};
Source/Crunch/Private/UI/Widget/ValueGauge.cpp:
// Copyright@ChenChao
#include "UI/Widget/ValueGauge.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
void UValueGauge::NativePreConstruct()
{
Super::NativePreConstruct();
// 初始化时应用默认颜色
if(ProgressBar) ProgressBar->SetFillColorAndOpacity(MinColor);
}
void UValueGauge::SetValue(float NewValue, float NewMaxValue)
{
if (NewMaxValue == 0)
{
UE_LOG(LogTemp, Warning, TEXT("Value Gauge: %s, 新的最大值不能是0."), *GetName());
return;
}
// 计算当前百分比
const float Percent = FMath::Clamp(NewValue / NewMaxValue, 0.0f, 1.0f);
// 颜色插值计算
const FLinearColor CurrentColor = FLinearColor::LerpUsingHSV(
MinColor,
MaxColor,
Percent
);
// 更新UI
if(ProgressBar)
{
ProgressBar->SetPercent(Percent);
ProgressBar->SetFillColorAndOpacity(CurrentColor);
}
if (ValueText)
{
//处理文本格式化:最大小数位为0
FNumberFormattingOptions FormattingOptions = FNumberFormattingOptions().SetMaximumIntegralDigits(0);
//设置文本框内容
ValueText->SetText(
FText::Format(//格式化文本
FTextFormat::FromString("{0}/{1}"),
FText::AsNumber(NewValue, &FormattingOptions),
FText::AsNumber(NewMaxValue, &FormattingOptions)
)
);
}
}