Download

Networked Weapon Traces not registering [Bug in Shooter Game w/ Video]

If two enemies are attacking from very near range their shots do not register over the network. This is not true for the server player. The best way to see this is to get right up on an enemy players left shoulder and fire into it. You’ll see that the trace spawns blood effects but there is no hit indicator or loss of life. I came across this issue while making my own 3rd person shooter based on the Shooter Game code. I thought I had implemented the replication wrong but after testing in Shooter Game one can easily see the issue exists there too.

In the video you can see shots from close range not registering, and then after moving back they register just fine. Again, this doesn’t happen if you’re the server.
https://youtube.com/watch?v=2Fdy38tlTHk

Debugs of the Traces show the lines drawing fine, and this is also demonstrated by the fact that blood effects are spawned. Does anyone have any idea what could be causing this issue?

Look at ShooterGame’s ShooterWeapon_Instant.cpp

Within the function:



void AShooterWeapon_Instant::ServerNotifyHit_Implementation(const FHitResult Impact, FVector_NetQuantizeNormal ShootDir, int32 RandomSeed, float ReticleSpread)


There is a check to determine if the hit is valid or not, I believe this is causing shots not to register if they are too close



// if we are within client tolerance
if (FMath::Abs(Impact.Location.Z - BoxCenter.Z) < BoxExtent.Z &&
	FMath::Abs(Impact.Location.X - BoxCenter.X) < BoxExtent.X &&
	FMath::Abs(Impact.Location.Y - BoxCenter.Y) < BoxExtent.Y)
{
	ProcessInstantHit_Confirmed(Impact, Origin, ShootDir, RandomSeed, ReticleSpread);
}
else
{
	UE_LOG(LogShooterWeapon, Log, TEXT("%s Rejected client side hit of %s (outside bounding box tolerance)"), *GetNameSafe(this), *GetNameSafe(Impact.GetActor()));
}


Obviously this is not the desired behavior so it should be fixed by Epic but that is where to look in the meantime

Hey Mentos,

Thanks for the tip on where to look. Turns out its not an issue with the BoxExtents (I tested initially by just commenting out the logic and just calling ProcessInstantHit no matter what) but the problem IS occurring in the ServerNotifyHit_Implementation. I put OnScreenDebugs to see which branch of the ‘if’ statement was being called when the hits failed to register and it turns out (would have seen it if I checked the logs in Shooter Game) the branch is:

if (ViewDotHitDir <= InstantConfig.AllowedViewDotHitDir)

It looks like the issue is with the ViewDotHitDir. I don’t know at the moment how to rectify this but I’m looking into it and will post a solution if I find one.

So what it looks like is happening is that when you’re really close the Dot of where you’re looking (uses the MuzzleLocation) and the HitLocation is breaking down. The value goes negative, much below the AllowedViewDotHitDir set in the InstantConfig. There are a few options to fix this, since its an anti-cheat measure. One work around is to add an additional condition to:

if ((ViewDotHitDir > InstantConfig.AllowedViewDotHitDir - WeaponAngleDot))

That ignores this necessity when players are very close. So the original becomes something like:

if ((ViewDotHitDir > InstantConfig.AllowedViewDotHitDir - WeaponAngleDot) || ((Instigator->GetActorLocation() - Impact.Location).Size() < 200.0f))

This seems less than optimal. In my case since my game is a 3rd person shooter I’m actually using the camera as the aim authority so using its location as the origin works well as a fix. At least it seems so. Well that is where I’m at right now. If I find a better fix I’ll update.