Strange Replication in C++

I tried posting this on the UE4 AnswerHub herebut haven’t had any luck with responses. I’m rather new with UE4’s multiplayer and the workflow for replication.

Hello all,

I have a projectile that a player shoots, then on impact with another player it plays a “hit” sound.

The Pawn class calls a Server RPC HandleFire that spawns the projectile.


void ATechnomancyCharacter::HandleFire_Implementation() {
  ...
  GetWorld()->SpawnActor<ABaseAttack>(SpawnLocation, Direction.Rotation(), SpawnParameters);
  ...
}
 

Then the OnProjectileOverlap function of the projectile calls a Client RPC called PlayClientSound


void ABaseAttack::OnProjectileOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
  ...
  IGameObject* OtherObject = Cast<IGameObject>(OtherActor);
  IGameObject* InstigatorObject = Cast<IGameObject>(Instigator);
  ...
  if (OtherObject && InstigatorObject)
  {
    ...
    InstigatorObject->PlayClientSound(HitSound);
  }
  ...
}  
 

Here is the Client RPC


void ATechnomancyCharacter::PlayClientSound_Implementation(USoundCue* Sound) {
  UGameplayStatics::PlaySound2D(GetWorld(), Sound);
}  
 

So in a multiplayer setting (listen server) I get some strange replication issues. When I play as a client things work as intended (meaning when I hit another player I get the “Hit” sound), but when I play as the server I will get the sound but it will SOMETIMES also play the sound on the client which is obviously not wanted.

Is there something I am doing wrong with the RPC calls I am making to cause this?

There is no need to use a RPC at all. Assuming that you projectile is replicated, you can simply check for overlaps on client and server and play the sound autonomously.

I believe I was trying that before with not using a client RPC at all. The issue I was having there is that it was playing the sound for everyone.

So how can I make it so it only plays the sound for the player firing the projectile.

When spawning the projectile you set the correct owner (replicated by default, see Actor.h). Then in OnProjectileOverlap you only play the sound if the player is also the owner.

Okay that sounds reasonable. I will try that later today and post back with results.