Create a HealthBarWidget.h
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "HealthBarWidget.generated.h"
UCLASS()
class BATTLETANK_API UHealthBarWidget : public UUserWidget
{
GENERATED_BODY()
public:
FORCEINLINE class UProgressBar *GetHealthBar() { return HealthBar; }
private:
UPROPERTY(meta = (BindWidget))
class UProgressBar *HealthBar;
};
Change the Parent Class of the HealthBar Blueprint to the new created C++ class UHealthBarWidget.
Make sure the name of your ProgressBar variable is HealthBar
In my case I created the Widget Component of the Tank Blueprint directly on the Tank constructor (as an inherited component), if you created adding the component on the blueprint, you need to find the class of the widget component on the Tank BeginPlay.
Tank.h:
//Foward Declarations
class UWidgetComponent;
// === Your code... === //
UFUNCTION(BlueprintPure, Category = "Health")
float GetHealthPercent() const;
UPROPERTY(VisibleAnywhere, Category = "Components")
UWidgetComponent *HealthBar{nullptr};
Tank.cpp:
//... Your includes...
#include "Components/WidgetComponent.h"
#include "UObject/ConstructorHelpers.h"
#include "Blueprint/UserWidget.h"
#include "../Widget/HealthBarWidget.h" // That is the location of the created c++ class for the widget
#include "Components/ProgressBar.h"
ATank::ATank()
{
HealthBar = CreateDefaultSubobject<UWidgetComponent>(FName("HealthBar Widget"));
static ConstructorHelpers::FClassFinder<UUserWidget> MenuWidgetClassFinder(TEXT("/Game/Source/UI/UI_HealthBar")); // Change the path to your file path, or just add the widget class on the Blueprint
HealthBar->SetWidgetClass(MenuWidgetClassFinder.Class);
HealthBar->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
}
void ATank::BeginPlay()
{
Super::BeginPlay();
HealthBar->InitWidget();
auto HealBarUserWidget = Cast<UHealthBarWidget>(HealthBar->GetUserWidgetObject());
if (!HealBarUserWidget)
{
UE_LOG(LogTemp, Error, TEXT("%s: Failed to Cast to UHealthBarWidget"), *GetOwner()->GetName());
return;
}
HealBarUserWidget->GetHealthBar()->PercentDelegate.BindUFunction(this, FName("GetHealthPercent"));
}
There is no need to pass any references/bind on the Blueprint.