After some debugging, it turns out the camera linetrace goes straight through objects, both worldstatics, worlddynamic, pawns, physics, collision boxes.
void ASWeapon::Fire()
{
/* Net Code
* Dont let client apply damage
*/
if (Role < ROLE_Authority)
{
ServerFire();
}
/* Trace the world, from the pawn eyes to crosshair location */
AActor* MyOwner = GetOwner();
if (MyOwner)
{
/* Trace */
FVector EyeLocation;
FRotator EyeRotation;
MyOwner->GetActorEyesViewPoint(EyeLocation, EyeRotation);
/* Weapon Trace */
FVector SocketLocation = MeshComponent->GetSocketLocation(MuzzleFireSocket);
FVector ShotDirection = EyeRotation.Vector();
FVector TraceEnd = EyeLocation + (ShotDirection * WeaponRange);
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(MyOwner);
QueryParams.AddIgnoredActor(this);
QueryParams.bTraceComplex = true;
QueryParams.bReturnPhysicalMaterial = true;
FHitResult CameraHit;
FHitResult GunHit;
/* Particle "Target" parameter */
EPhysicalSurface SurfaceType = SurfaceType_Default;
/* Camera Trace */
GetWorld()->LineTraceSingleByChannel(CameraHit, EyeLocation, TraceEnd, ECollisionChannel::ECC_Visibility, QueryParams);
AActor* HitActor = CameraHit.GetActor();
FVector ImpactPointCamera = CameraHit.ImpactPoint;
GetWorld()->LineTraceSingleByChannel(GunHit, SocketLocation, ImpactPointCamera, ECollisionChannel::ECC_Visibility, QueryParams);
AActor* HitActorGun = GunHit.GetActor();
FVector ImpactPointGun = GunHit.ImpactPoint;
SurfaceType = UPhysicalMaterial::DetermineSurfaceType(GunHit.PhysMaterial.Get());
if (DebugWeaponDrawing > 0)
{
DrawDebugLine(GetWorld(), EyeLocation, TraceEnd, FColor::Red, true, -1.0f, 0, 1.0f);
DrawDebugLine(GetWorld(), SocketLocation, ImpactPointGun, FColor::Blue, true, -1.0f, 0, 1.0f);
}
if (HitActor == HitActorGun)
{
/* Headshot */
if (SurfaceType == SURFACE_FLESHVULNERABLE)
{
float CriticalDamage = BaseDamage * CriticalMultiplier;
UGameplayStatics::ApplyPointDamage(HitActorGun, CriticalDamage, ShotDirection, GunHit, MyOwner->GetInstigatorController(), this, DamageType);
}
else if (SurfaceType == SURFACE_FLESHDEFAULT)
{
UGameplayStatics::ApplyPointDamage(HitActorGun, BaseDamage, ShotDirection, GunHit, MyOwner->GetInstigatorController(), this, DamageType);
}
}
PlayImpactEffects(SurfaceType, ImpactPointGun);
PlayFireEffects(ImpactPointGun);
if (Role == ROLE_Authority)
{
HitScanTrace.TraceTo = ImpactPointGun;
HitScanTrace.SurfaceType = SurfaceType;
}
LastFireTime = GetWorld()->TimeSeconds;
}
}
Red lines are cameratrace, blue lines are guntrace.
- All objects in the scene are set to BLOCKALL, meshes and objects
- It has been tested with different collision channels both custom and pre, same results.
- Functionality is same on server/client.