Hey everyone,
I’ve been working on a multiplayer game in Unreal Engine and I’m running into an issue with updating the player’s HUD when they take damage.
Currently, I have a function UpdateHealthHud()
in my PlayerHUD
class, and this function is bound to a public static delegate PlayerHealthUpdated
. The strange thing is that when this event is called, the health HUD updates across all clients. I’m not entirely sure why this is happening.
My question is, do the event broadcasts get replicated across all the networks by default, or is there something else I need to set up in the PlayerHUD
?
Any insights or suggestions would be greatly appreciated!
PlayerEvent
//----> Player Event.h
DECLARE_MULTICAST_DELEGATE_TwoParams(FHealthUpdated, float, float)
UCLASS()
class CARGO_API UPlayerEvents : public UObject
{
GENERATED_BODY()
public:
static FHealthUpdated HealthUpdatedEvent;
};
//----> Player Event.cpp
#include "PlayerEvents.h"
FHealthUpdated UPlayerEvents::HealthUpdatedEvent;
PlayerHUD.cpp
void APlayerHUD::PostInitProperties()
{
Super::PostInitProperties();
UPlayerEvents::HealthUpdatedEvent.AddUObject(this,&APlayerHUD::UpdateHealth);
}
void APlayerHUD::UpdateHealth(float Health, float MaxHealth) const
{
if(CharacterOverlay && CharacterOverlay->HealthBar && CharacterOverlay->HealthText)
{
const float percentage = Health / MaxHealth;
CharacterOverlay->HealthBar->SetPercent(percentage);
const FString HealthText = FString::Printf(TEXT("%d/%d"), FMath::CeilToInt(Health),FMath::CeilToInt(MaxHealth));
CharacterOverlay->HealthText->SetText(FText::FromString(HealthText));
}
}
FHealthUpdated UPlayerEvents::HealthUpdatedEvent;
BaseCharacter.cpp
// Called when the game starts or when spawned
void ABaseCharacter::BeginPlay()
{
Super::BeginPlay();
if(HasAuthority())
{
OnTakeAnyDamage.AddDynamic(this, &ABaseCharacter::ReceiveDamage);
}
}
void ABaseCharacter::ReceiveDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType,
AController* InstigatorController, AActor* DamageCauser)
{
ABaseCharacter* character = Cast<ABaseCharacter>(DamagedActor);
if(character)
{
character->CurrentHealth = FMath::Clamp(CurrentHealth - 10, 0.0f, MaxHealth);
}
}
void ABaseCharacter::OnRep_Health() const
{
if(IsLocallyControlled())
{
UPlayerEvents::HealthUpdatedEvent.Broadcast(CurrentHealth, MaxHealth);
}
}