void ASWeaponInstant::FireWeapon() { const FVector AimDir = GetAdjustedAim(); const FVector CameraPos = GetCameraDamageStartLocation(AimDir); const FVector EndPos = CameraPos + (AimDir * WeaponRange); /* Check for impact by tracing from the camera position */ FHitResult Impact = WeaponTrace(CameraPos, EndPos); const FVector MuzzleOrigin = GetMuzzleLocation(); FVector AdjustedAimDir = AimDir; if (Impact.bBlockingHit) { /* Adjust the shoot direction to hit at the crosshair. */ AdjustedAimDir = (Impact.ImpactPoint - MuzzleOrigin).GetSafeNormal(); /* Re-trace with the new aim direction coming out of the weapon muzzle */ Impact = WeaponTrace(MuzzleOrigin, MuzzleOrigin + (AdjustedAimDir * WeaponRange)); } else { /* Use the maximum distance as the adjust direction */ Impact.ImpactPoint = FVector_NetQuantize(EndPos); } ProcessInstantHit(Impact, MuzzleOrigin, AdjustedAimDir); }
void ASWeaponInstant::FireWeapon() { const FVector AimDir = GetAdjustedAim(); const FVector StartPos = GetCameraDamageStartLocation(AimDir); const FVector EndPos = StartPos + (AimDir * WeaponRange); const FHitResult Impact = WeaponTrace(StartPos, EndPos); ProcessInstantHit(Impact, StartPos, AimDir); }
void AAmethystWeapon_Projectile::FireWeapon() { FVector ShootDir = GetAdjustedAim(); FVector Origin = GetMuzzleLocation(); // trace from camera to check what's under crosshair const float ProjectileAdjustRange = 10000.0f; const FVector StartTrace = GetCameraDamageStartLocation(ShootDir); const FVector EndTrace = StartTrace + ShootDir * ProjectileAdjustRange; FHitResult Impact = WeaponTrace(StartTrace, EndTrace); // and adjust directions to hit that actor if (Impact.bBlockingHit) { const FVector AdjustedDir = (Impact.ImpactPoint - Origin).SafeNormal(); bool bWeaponPenetration = false; const float DirectionDot = FVector::DotProduct(AdjustedDir, ShootDir); if (DirectionDot < 0.0f) { // shooting backwards = weapon is penetrating bWeaponPenetration = true; } else if (DirectionDot < 0.5f) { // check for weapon penetration if angle difference is big enough // raycast along weapon mesh to check if there's blocking hit FVector MuzzleStartTrace = Origin - GetMuzzleDirection() * 150.0f; FVector MuzzleEndTrace = Origin; FHitResult MuzzleImpact = WeaponTrace(MuzzleStartTrace, MuzzleEndTrace); if (MuzzleImpact.bBlockingHit) { bWeaponPenetration = true; } } if (bWeaponPenetration) { // spawn at crosshair position Origin = Impact.ImpactPoint - ShootDir * 10.0f; } else { // adjust direction to hit ShootDir = AdjustedDir; } } ServerFireProjectile(Origin, ShootDir); }
void AShooterWeapon_Instant::FireWeapon() { const int32 RandomSeed = FMath::Rand(); FRandomStream WeaponRandomStream(RandomSeed); const float CurrentSpread = GetCurrentSpread(); const float ConeHalfAngle = FMath::DegreesToRadians(CurrentSpread * 0.5f); const FVector AimDir = GetAdjustedAim(); const FVector StartTrace = GetCameraDamageStartLocation(AimDir); const FVector ShootDir = WeaponRandomStream.VRandCone(AimDir, ConeHalfAngle, ConeHalfAngle); const FVector EndTrace = StartTrace + ShootDir * InstantConfig.WeaponRange; const FHitResult Impact = WeaponTrace(StartTrace, EndTrace); ProcessInstantHit(Impact, StartTrace, ShootDir, RandomSeed, CurrentSpread); CurrentFiringSpread = FMath::Min(InstantConfig.FiringSpreadMax, CurrentFiringSpread + InstantConfig.FiringSpreadIncrement); }