How should I implement HP Bar for ai and player?

Thank you so much for your response!

It’s not an interface that can be used in Blueprint!

I changed the code as I understood it. For now, Deligate has set up player and ai separately.

player code

// HP
protected:
	virtual void SettingHpBar(class UOLHpBarWidget* HpWidget) override;	
	virtual void DrinkHpPotion(float HpAmount) override;	
	virtual void ChangeHp() override;	

void AOLCharacterPlayer::SettingHpBar(UOLHpBarWidget* HpBar)
{
	if (IsPlayerControlled())
	{
		UOLHpBarWidget* HpBarWidget = Cast<UOLHpBarWidget>(HpBar);	// 초기화
		OnHpChange.AddUObject(HpBarWidget, &UOLHpBarWidget::UpdateHpBar);
		UE_LOG(LogTemp, Warning, TEXT("Player Setting HpBar"));
	}
}

void AOLCharacterPlayer::DrinkHpPotion(float HpAmount)
{
	Hp = FMath::Clamp(Hp + HpAmount, 0.0f, MaxHp);	
	ChangeHp();	
}

void AOLCharacterPlayer::ChangeHp()
{
	OnHpChange.Broadcast(Hp / MaxHp);	
	UE_LOG(LogTemp, Warning, TEXT("Player Change Hp"));
}

First of all, the important thing in the code above is that there are a total of 4 npc in the map, UE_LOG (LogTemp, Warning, TEXT (“Player Setting HpBar”) including player; that log appears 5 times. I don’t know why. And the important thing is that when a player is attacked, ai seems to share that widget as well. There are fewer widgets together.

ai code

AOLNPCBasic::AOLNPCBasic()
{
	// HP Bar
	HpBar = CreateDefaultSubobject< UWidgetComponent>(TEXT("HpBar"));
	HpBar->SetupAttachment(GetMesh());	// 메시에 부착
	HpBar->SetRelativeLocation(FVector(0.0f, 0.0f, 202.0f));	// 머리 위에 위치하게(부착된 메시를 기준으로 움직임)
	// 월드공간 기준으로 배치될지(3D UI), 스크린 좌표 기준으로 배치될지(2D UI) 결정
	// Screen은 절대로 화면 밖으로 짤리지 않는다
	HpBar->SetWidgetSpace(EWidgetSpace::Screen);
	HpBar->SetDrawSize(FVector2D(150.0f, 20.0f));	// 위젯 크기
	HpBar->SetCollisionEnabled(ECollisionEnabled::NoCollision);	// 충돌 없음

void AOLNPCBasic::BeginPlay()
{
	Super::BeginPlay();

	// HP Bar
	UUserWidget* Widget = HpBar->GetUserWidgetObject();
	UOLHpBarWidget* HpWidget = Cast<UOLHpBarWidget>(Widget);
	OnHpChange.AddUObject(HpWidget, &UOLHpBarWidget::UpdateHpBar);

}

void AOLNPCBasic::ChangeHp()
{
	OnHpChange.Broadcast(Hp / MaxHp);	// 체력이 바뀌면 신호 보내기, 해당 캐릭터
	UE_LOG(LogTemp, Warning, TEXT("NPC Change Hp"));
}

Base code


float AOLCharacterBase::TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

	Hp = FMath::Clamp(Hp - DamageAmount, 0.0f, MaxHp);	// 체력  업데이트

	if (AOLCharacterPlayer* Player = Cast<AOLCharacterPlayer>(HpUpdateTarget))
	{
		IOLUpdateHpInterface* HpInterface = Cast<IOLUpdateHpInterface>(Player);
		HpInterface->ChangeHp();
	}
	else if (AOLNPCBasic* NPC = Cast<AOLNPCBasic>(HpUpdateTarget))
	{
		IOLUpdateHpInterface* HpInterface = Cast<IOLUpdateHpInterface>(NPC);
		HpInterface->ChangeHp();
	}
	

	if (Hp <= 0.0f && !IsDead)
	{
		DeadCheck();
	}

	return DamageAmount;
}

The reason I wrote the if statement in the code above is because if a player is attacked, the widget in the ai keeps moving the same way as the player’s widget. But it didn’t work. I think I’m doing something wrong. There are so many things I don’t know.. (sorry)

If there’s a change in fitness, I’ve made it to log in withget. If a player is attacked, only one player has a change in fitness, so with with without, you’ll only get one log. But a total of 5 logs. Including ai’s.
And importantly, if the ai is actually attacked, the widgets in all the ai will change…