Networking: The variable is not set from the client

I have a second question related to the networking. If i run this on server it works fine, but for a Client if I shot a player it doesn’t change his current health. The code doesn’t enter in TakeDamageRPC_Implementation function.The health variable is replicated.

if (AMyCharacter* EnemyPlayer = dynamic_cast<AMyCharacter*>(Hit.GetActor())) {
EnemyPlayer->TakeDamage(DealtDamage, DamageEvent, OwningPlayer->GetController(), this);

float AMyCharacter::TakeDamage(float DamageAmount, struct FDamageEvent const & DamageEvent, AController * EventInstigator, AActor * DamageCauser)
        //works fine until here
	return Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

UFUNCTION(Server, Reliable, WithValidation)
void TakeDamageRPC(float DamageTaken);

void AMyCharacter::TakeDamageRPC_Implementation(float DamageTaken) {
   // reduce health implementation


Hello Desfrau,

I you are almost correct. What you need to make sure that the TakeDamage function is ALWAYS called on the server. Also make sure that the actor who is calling the TakeDamage() function is owned by the client. Ownership is very important here.

What you could do is:

In Fire functionality:


In my project I approached it as follows:

  1. Get Start, End vectors in client side, and pass them to the server to perform a trace.
  2. While executed on server, I check if the trace hit something (I’m still on server) so I hit somebody, so I call the TakeDamage() on server ALWAYS
  3. Inside the takedamage I execute the TakeHealth() which just substracts the Health variable which is set as replicated

That’s a HitScan approach, for Projectile you could do simply get the firing direction and pass it to the server to spawn projectile.

Anyway, make sure you are executing TakeDamage() on SERVER

Yep, you’re right buddy! Thanks for the advice :slight_smile: