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…