You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UE5/C++:运行时修改Progress Bar背景图片无显示问题求助

UE运行时修改ProgressBar背景图片无变化问题

我是UE新手,开发HUD时遇到Progress Bar相关问题:运行时修改Progress Bar的背景图片,日志显示流程正常但屏幕无变化,求帮忙排查。

我的代码

.h 文件

UPROPERTY(EditAnywhere, meta=(BindWidget))
    class UProgressBar* IconSlot1;
    UPROPERTY(EditAnywhere, meta=(BindWidget))
    class UProgressBar* IconSlot2;
    UPROPERTY(EditAnywhere, meta=(BindWidget))
    class UProgressBar* IconSlot3;
    UPROPERTY(EditAnywhere)
    TArray<class UIconSlot*> IconArr;
    UPROPERTY(VisibleAnywhere)
    TArray<class UProgressBar*> SlotArr;

.cpp 文件

void UPlayerUI::SetSlotIcon(const TEnumAsByte<EDamageClass>& DamageClass)
{
    const auto EmptySlot = GetFreeSlot();
    const auto Icon = GetImage(DamageClass);

    if (IsValid(EmptySlot) && IsValid(Icon))
    {
        FProgressBarStyle Style = EmptySlot -> GetWidgetStyle();
        
            if (Style.BackgroundImage.GetResourceObject() == nullptr)
            {
                FSlateImageBrush Brush = FSlateImageBrush(Icon, FVector2d(100, 100));
                Style.SetBackgroundImage(Brush);
                UE_LOG(LogTemp, Warning, TEXT("Image slot is set"));
            }
            else
            {
                UE_LOG(LogTemp, Warning, TEXT("Image slot isn't empty"));
                return;
            }

            Slots.Add(EmptySlot, DamageClass);
    }
}

UProgressBar* UPlayerUI::GetFreeSlot()
{
    for (const auto IconSlot : SlotArr)
    {
        if (!Slots.Contains(IconSlot))
        {
            UE_LOG(LogTemp, Warning, TEXT("Slot found"));
            return IconSlot;
        }
    }
    
    return nullptr;
}

UTexture2D* UPlayerUI::GetImage(const TEnumAsByte<EDamageClass>& DamageClass)
{
    for (const auto IconImage : IconArr)
    {
        if (IconImage -> DamageClass == DamageClass && !Icons.Contains(IconImage))
        {
            UE_LOG(LogTemp, Warning, TEXT("Image found"));
            Icons.Add(IconImage, DamageClass);
            return IconImage -> Image;
        }
    }
    
    return nullptr;
}

问题排查与修复

核心问题

你当前代码中,FProgressBarStyle Style = EmptySlot->GetWidgetStyle();是创建了样式的副本,修改这个副本后没有把它重新赋值给ProgressBar,导致UI无法感知到样式变化。

修复代码

修改SetSlotIcon函数,在修改完样式后添加赋值操作:

void UPlayerUI::SetSlotIcon(const TEnumAsByte<EDamageClass>& DamageClass)
{
    const auto EmptySlot = GetFreeSlot();
    const auto Icon = GetImage(DamageClass);

    if (IsValid(EmptySlot) && IsValid(Icon))
    {
        FProgressBarStyle Style = EmptySlot->GetWidgetStyle();
        
        if (Style.BackgroundImage.GetResourceObject() == nullptr)
        {
            FSlateImageBrush Brush = FSlateImageBrush(Icon, FVector2d(100, 100));
            Style.SetBackgroundImage(Brush);
            UE_LOG(LogTemp, Warning, TEXT("Image slot is set"));
            // 关键:将修改后的样式赋值回ProgressBar
            EmptySlot->SetWidgetStyle(Style);
        }
        else
        {
            UE_LOG(LogTemp, Warning, TEXT("Image slot isn't empty"));
            return;
        }

        Slots.Add(EmptySlot, DamageClass);
    }
}

额外检查项

  • 确认SlotArr已正确初始化:在UI的NativeConstruct函数中,把IconSlot1、IconSlot2、IconSlot3添加到SlotArr里,否则GetFreeSlot找不到可用插槽。
  • 检查纹理设置:确保Icon对应的UTexture2D的SRGB和UI Compression设置正确,避免图片无法显示。
  • 尺寸匹配:FSlateImageBrush的尺寸(100x100)尽量和ProgressBar的实际渲染尺寸一致,防止图片被拉伸或裁剪。

内容的提问来源于stack exchange,提问作者hof13nn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:15:36