Hello everyone,
I’m working on a top down shooter and currently implementing a shooting system. Everything seems fine until my client starts shooting and only damages other players locally. Server does damage to all clients tho.
Here is my function for shooting:
void AWeapon::Fire()
{
if (WeaponConfig.currentMagAmmo > 0)
{
ABaseHero* Character = Cast<ABaseHero>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
if (!Character) return;
FVector Start, End, Direction, MouseWorldLoc, MouseWorldDir;
APlayerController* Controller = UGameplayStatics::GetPlayerController(GetWorld(), 0);
Controller->DeprojectMousePositionToWorld(MouseWorldLoc, MouseWorldDir);
FVector tempDir = Character->TopDownCameraComp->GetForwardVector();
FVector tempEnd = MouseWorldDir * 3000.0f + MouseWorldLoc;
FCollisionQueryParams Params = FCollisionQueryParams(FName(TEXT("My Trace")), true, this);
Params.bTraceComplex = true;
FHitResult MouseTraceHit(ForceInit);
GetWorld()->LineTraceSingleByChannel(MouseTraceHit, MouseWorldLoc, tempEnd, ECC_Pawn, Params);
Start = TheMesh->GetSocketLocation(TEXT("MuzzleSocket"));
End = MouseTraceHit.ImpactPoint;
End.X += FMath::RandRange(-CurrentSpread, CurrentSpread);
End.Y += FMath::RandRange(-CurrentSpread, CurrentSpread);
End.Z += FMath::RandRange(-CurrentSpread, CurrentSpread);
FHitResult Hit(ForceInit);
GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Pawn, Params);
ABaseHero* Hero = Cast<ABaseHero>(Hit.GetActor());
if (Hero && Hero != Character)
{
Hero->TakeHealth(30.0f);
GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, FString::Printf(TEXT("Health: %.2f"), Hero->GetHealth()));
}
DrawDebugLine(GetWorld(), Start, End, FColor::Red, false, 3.0f);
//DrawDebugPoint(GetWorld(), End, 3.0f, FColor::Red, false, 3.0f);
if (ShotSound)
{
UGameplayStatics::PlaySoundAtLocation(GetWorld(), ShotSound, Start);
}
if (Role < ROLE_Authority)
{
GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Green, TEXT("Not server, calling him!"));
ServerFire();
GEngine->AddOnScreenDebugMessage(2, 2.0f, FColor::Green, TEXT("Not server, called him!"));
}
}
}
And my ServerFire function is:
Weapon.h
/** Ask server to perform a shot */
UFUNCTION(Reliable, Server, WithValidation)
void ServerFire();
virtual void ServerFire_Implementation();
virtual bool ServerFire_Validate();
Weapon.cpp
void AWeapon::ServerFire_Implementation()
{
Fire();
}
My sprinting and item pickup is implemented absolutely the same way and it works just fine. For some reason it doesn’t work for me here…
Just to clarify: The health is replicated property and works fine because server causes damage properly and replicates to all clients.
Any thoughts?