Hi everyone. I’m implementing HP Bar for ai and player right now. At first, I only made player’s Hp Bar visible.
I made the widget pop on top of my head as shown in the picture above.

The player made it appear on the screen as shown in the picture above.
Now ai and player are inheriting the base class. Base has set up the deligate. Let me show you the code.
HpWidget code.
void UOLHpBarWidget::NativeConstruct()
{
Super::NativeConstruct();
HpBarProgress = Cast<UProgressBar>(GetWidgetFromName(TEXT("HpBar")));
ensure(HpBarProgress);
APawn* Player = GetOwningPlayerPawn();
ensure(Player);
IOLHpInterface* CharacterInterface = Cast<IOLHpInterface>(Player);
ensure(CharacterInterface);
CharacterInterface->SettingHpBar(this);
}
void UOLHpBarWidget::UpdateHpBar(float CurrentHp)
{
UE_LOG(LogTemp, Error, TEXT("Update Hpabar?"));
if (HpBarProgress)
{
HpBarProgress->SetPercent(CurrentHp);
UE_LOG(LogTemp, Error, TEXT("Update Hp"));
}
}
Base code inherited by ai and Player.
// .h
protected:
virtual void SettingHpBar(class UOLHpBarWidget* HpWidget) override;
virtual void ChangeHp() override;
class UOLHpBarWidget* HpBarWidget;
// .cpp
void AOLCharacterBase::SettingHpBar(UOLHpBarWidget* HpWidget)
{
HpBarWidget = HpWidget;
}
void AOLCharacterBase::ChangeHp()
{
}
Player Code
// .h
DECLARE_MULTICAST_DELEGATE_OneParam(FOnHpChangeDelegate, float /*CurrenHp*/);
public:
FOnHpChangeDelegate OnHpChange;
// HP
protected:
virtual void SettingHpBar(class UOLHpBarWidget* HpWidget) override; // A function for setting up a deligate.
virtual void ChangeHp() override; // Function to reflect hp in widget
// .cpp
void AOLCharacterPlayer::SettingHpBar(UOLHpBarWidget* HpWidget)
{
//UOLHpBarWidget* HpBarWidget = Cast<UOLHpBarWidget>(HpBar);
OnHpChange.AddUObject(HpBarWidget, &UOLHpBarWidget::UpdateHpBar);
}
void AOLCharacterPlayer::ChangeHp()
{
OnHpChange.Broadcast(Hp / MaxHp);
UE_LOG(LogTemp, Warning, TEXT("Player Change Hp"));
}
ai Code
// .h
DECLARE_MULTICAST_DELEGATE_OneParam(FOnHpChangeDelegate, float /*CurrenHp*/);
public:
FOnHpChangeDelegate OnHpChange;
protected:
virtual void SettingHpBar(class UOLHpBarWidget* HpWidget) override; // A function for setting up a deligate.
virtual void ChangeHp() override; // Function to reflect hp in widget
// .cpp
void AOLNPCBasic::SettingHpBar(UOLHpBarWidget* HpWidget)
{
//UOLHpBarWidget* HpBarWidget = Cast<UOLHpBarWidget>(HpBar);
OnHpChange.AddUObject(HpBarWidget, &UOLHpBarWidget::UpdateHpBar);
}
void AOLNPCBasic::ChangeHp()
{
OnHpChange.Broadcast(Hp / MaxHp);
UE_LOG(LogTemp, Warning, TEXT("NPC Change Hp"));
}
The code is too long. Sorry, but ChangeHp functions are called when being attacked or recovering from physical strength. Logs are visible for both ai and player. When ChangeHp is called, the UpdateHpBar function is called. But the log doesn’t show up at this time. I think there’s a problem with widget settings, but I don’t know how to fix it…
For reference, the reason why ai and player have the same function and the same content was that when changeHp was written in Base, ai referred to the player’s widget as it was, and when the player was attacked, the widget in ai moved the same way as the player.
This is getting too long. Thank you for reading. I really appreciate your help.
(The language may not be natural because of the use of a translator.)