HasAuthority preventing Client replication

I’m trying to do basic variable replication with cpp. However, I found out that for some reason, if I use HasAuthority before replicating, the clients can’t replicate the variable to others, so I have to get rid of it(but the server can). I heard it was bad practice, so what am I doing wrong?

Here’s my code:

float AFPSCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	float Result = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
	UE_LOG(LogTemp, Warning, TEXT("Damage taken: %f"), DamageAmount);

	if (HasAuthority()) {		
		Health -= DamageAmount;
		OnRep_Health();
	}

I’ve tried

	Health -= DamageAmount;
	if (HasAuthority()) {		
		OnRep_Health();
	}

but it didn’t change anything. Again, clients can’t replicate, only the server can.
The only way I could get it working is getting rid of the Hasauthority check, which seems to make it vulnerable to cheats, so what should I do?

Replication is when the Server keeps a variable in sync on Clients.
A Client can’t replicate a variable to the server, however a Client can send an RPC with a variable as the parameter and the Server then decides if it wants to accept it and replicate it back to the Clients.

TakeDamage is something that should only happen on the Server otherwise the Clients will go out of sync.

The only reason why you would call OnRep_Health on the server is to trigger this function server-side to keep it consistent with the behavior of Blueprint RepNotify events which also trigger server-side.
The Client will receive the OnRep_Health event to keep the Client in sync whenever you change the Health value to something that is not already set on the Client.

I checked the definition of TakeDamage on the Actor.h file, but there were nothing I could find that was related to RPC UFUNCTIONs.

TakeDamage is something that should only happen on the Server

Do you mean I should make it run only on the server, or it automatically runs only on the server?

I’ve tried doing that after posting this, but the engine complained something about the actor not having a owning controller, and the function got ignored.
It looked something like this:

void AFPSCharacter::ServerDamagePlayer_Implementation(float value)
{
	Health = FMath::Max(0, (Health - value));
	UE_LOG(LogTemp, Warning, TEXT("Health replicated"));
	if (GetNetMode() != NM_DedicatedServer)
	{
		OnRep_Health();
	}
}

This was UFUNCTION(Server, Reliable). Am I doing something wrong?

I literally just covered this in a Game sub on reddit. Wild coincidence.

Here’s a generalized implementation. It’s in BP but translation shouldn’t be difficult.

Take your hit result (damage causer), calculate damage and feed it to one of the Apply Damage events. In this demonstration the servers projectile is handling the dmg calcs.

[Projectile Class]

Event is executed and calls a Server event to apply the damage to the Player State Health variable.

[Pawn Class]

We then set a “Display Health” variable on the Pawn. Said variable is RepNotify.

The OnRep Function sets the health in the UI.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.