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 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);
}
예제 #3
0
void ABaseWeapon::Instant_Fire()
{
	const int32 RandomSeed = FMath::Rand();
	FRandomStream WeaponRandomStream(RandomSeed);
	const float CurrentSpread = WeaponConfig.WeaponSpread;
	const float SpreadCone = FMath::DegreesToRadians(WeaponConfig.WeaponSpread * 0.5);
	const FVector AimDir = MyPawn->GetActorForwardVector();
	const FVector StartTrace = MyPawn->GetActorLocation();
	const FVector ShootDir = WeaponRandomStream.VRandCone(AimDir, SpreadCone, SpreadCone);
	FVector EndTrace;

	if (Target)
	{
		FVector TargetDir = (MyPawn->GetActorLocation() - Target->GetActorLocation());
		TargetDir.Normalize();
		FVector ShootDir2 = WeaponRandomStream.VRandCone(-TargetDir, SpreadCone, SpreadCone);
		EndTrace = StartTrace + ShootDir2 * WeaponConfig.WeaponRange;
	}
	else
	{
		EndTrace = StartTrace + ShootDir * WeaponConfig.WeaponRange;
	}

	const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);
	SpawnParticle(EndTrace);
	HitActor = Cast<AActor>(Impact.GetActor());

	//DrawDebugLine(GetWorld(), StartTrace, EndTrace, FColor::Red, false, 1.0f);

	if (HitActor)
	{
		Server_DealDamage(Impact, ShootDir, WeaponConfig);
	}
}
예제 #4
0
//If we are firing trace the beam
void AAssaultWeapon::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );
    if(firing){
        WeaponTrace();
    }
}
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 AFP_FirstPersonCharacter::OnFire()
{
	// Play a sound if there is one
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if(FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if(AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}

	// Now send a trace from the end of our gun to see if we should hit anything
	APlayerController* PlayerController = Cast<APlayerController>(GetController());
	
	// Calculate the direction of fire and the start location for trace
	FVector CamLoc;
	FRotator CamRot;
	PlayerController->GetPlayerViewPoint(CamLoc, CamRot);
	const FVector ShootDir = CamRot.Vector();

	FVector StartTrace = FVector::ZeroVector;
	if (PlayerController)
	{
		FRotator UnusedRot;
		PlayerController->GetPlayerViewPoint(StartTrace, UnusedRot);

		// Adjust trace so there is nothing blocking the ray between the camera and the pawn, and calculate distance from adjusted start
		StartTrace = StartTrace + ShootDir * ((GetActorLocation() - StartTrace) | ShootDir);
	}

	// Calculate endpoint of trace
	const FVector EndTrace = StartTrace + ShootDir * WeaponRange;

	// Check for impact
	const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);

	// Deal with impact
	AActor* DamagedActor = Impact.GetActor();
	UPrimitiveComponent* DamagedComponent = Impact.GetComponent();

	// If we hit an actor, with a component that is simulating physics, apply an impulse
	if ((DamagedActor != NULL) && (DamagedActor != this) && (DamagedComponent != NULL) && DamagedComponent->IsSimulatingPhysics())
	{
		DamagedComponent->AddImpulseAtLocation(ShootDir*WeaponDamage, Impact.Location);
	}
}
void ASWeaponInstant::SimulateInstantHit(const FVector& Origin)
{
	const FVector StartTrace = Origin;
	const FVector AimDir = GetAdjustedAim();
	const FVector EndTrace = StartTrace + (AimDir * WeaponRange);

 	const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);
	if (Impact.bBlockingHit)
	{
		SpawnImpactEffects(Impact);
		SpawnTrailEffects(Impact.ImpactPoint);
	}
	else
	{
		SpawnTrailEffects(EndTrace);
	}

	// Do not spawn near-hit if we actually hit a pawn
	if (Impact.GetActor() && Impact.GetActor()->IsA(ASCharacter::StaticClass()))
	{
		return;
	}

	for (FConstPawnIterator It = GetWorld()->GetPawnIterator(); It; It++)
	{
		// Find a locally controlled pawn that is not the instigator of the hit.
		ASCharacter* OtherPawn = Cast<ASCharacter>(*It);
		if (OtherPawn && OtherPawn != GetPawnOwner() && OtherPawn->IsLocallyControlled())
		{
			// Calculate shortest distance to point. (using the estimated eye height)
			const float DistanceToPawn = FVector::CrossProduct(AimDir, OtherPawn->GetActorLocation() - Origin).Size();

			/* Owner can be lost before client gets to simulate the hit. */
			ASCharacter* P = GetPawnOwner();
			if (P)
			{
				FVector LookAt = (OtherPawn->GetActorLocation() - GetPawnOwner()->GetActorLocation());
				LookAt.Normalize();
				float LookDot = FVector::DotProduct(AimDir, LookAt);

				if (DistanceToPawn < NearHitMaxDistance && LookDot > 0)
				{
					// TODO: Play at nearest "almost" hit location.
					const FVector SoundLocation = Origin + (AimDir * DistanceToPawn);

					// Volume is based on distance to missed shot
					float Volume = FMath::Clamp(1 - (DistanceToPawn / NearHitMaxDistance), 0.1f, 1.0f);

					UGameplayStatics::PlaySoundAtLocation(this, NearHitSound, /*SoundLocation*/ OtherPawn->GetActorLocation(), Volume);
				}
			}
		}
	}
}
예제 #8
0
void AWeapon::Instant_Fire()
{

		const int32 RandomSeed = FMath::Rand();
		FRandomStream WeaponRandomStream(RandomSeed);
		const float CurrentSpread = WeaponConfig.WeaponSpread;
		const float SpreadCone = FMath::DegreesToRadians(WeaponConfig.WeaponSpread * 0.5);
		const FVector AimDir = WeaponMesh->GetSocketRotation("MF").Vector();
		const FVector StartTrace = WeaponMesh->GetSocketLocation("MF");
		const FVector ShootDir = WeaponRandomStream.VRandCone(AimDir, SpreadCone, SpreadCone);
		const FVector EndTrace = StartTrace + ShootDir * WeaponConfig.WeaponRange;
		const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);

		ProcessInstantHit(Impact, StartTrace, ShootDir, RandomSeed, CurrentSpread);


}
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);
}
예제 #10
0
void ATraceWeapon::Attack()
{
	Super::Attack();
	

	FVector Start = GetActorLocation();

	FVector Direction = Instigator->GetActorRotation().Vector();
	FVector End = Start + Direction * Range;

	FHitResult Impact = WeaponTrace(Start, End);

	HitResult(Impact, Start, Direction);

	


}
void ASWeaponInstant::SimulateInstantHit(const FVector& ImpactPoint)
{
    const FVector MuzzleOrigin = GetMuzzleLocation();

    /* Adjust direction based on desired crosshair impact point and muzzle location */
    const FVector AimDir = (ImpactPoint - MuzzleOrigin).GetSafeNormal();

    const FVector EndTrace = MuzzleOrigin + (AimDir * WeaponRange);
    const FHitResult Impact = WeaponTrace(MuzzleOrigin, EndTrace);

    if (Impact.bBlockingHit)
    {
        SpawnImpactEffects(Impact);
        SpawnTrailEffects(Impact.ImpactPoint);
    }
    else
    {
        SpawnTrailEffects(EndTrace);
    }
}
void AShooterWeapon_Instant::SimulateInstantHit(const FVector& ShotOrigin, int32 RandomSeed, float ReticleSpread)
{
    FRandomStream WeaponRandomStream(RandomSeed);
    const float ConeHalfAngle = FMath::DegreesToRadians(ReticleSpread * 0.5f);

    const FVector StartTrace = ShotOrigin;
    const FVector AimDir = GetAdjustedAim();
    const FVector ShootDir = WeaponRandomStream.VRandCone(AimDir, ConeHalfAngle, ConeHalfAngle);
    const FVector EndTrace = StartTrace + ShootDir * InstantConfig.WeaponRange;

    FHitResult Impact = WeaponTrace(StartTrace, EndTrace);
    if (Impact.bBlockingHit)
    {
        SpawnImpactEffects(Impact);
        SpawnTrailEffect(Impact.ImpactPoint);
    }
    else
    {
        SpawnTrailEffect(EndTrace);
    }
}
예제 #13
0
void AShooterWeapon_Instant::SpawnImpactEffects(const FHitResult& Impact)
{
	if (ImpactTemplate && Impact.bBlockingHit)
	{
		FHitResult UseImpact = Impact;

		// trace again to find component lost during replication
		if (!Impact.Component.IsValid())
		{
			const FVector StartTrace = Impact.ImpactPoint + Impact.ImpactNormal * 10.0f;
			const FVector EndTrace = Impact.ImpactPoint - Impact.ImpactNormal * 10.0f;
			FHitResult Hit = WeaponTrace(StartTrace, EndTrace);
			UseImpact = Hit;
		}

		AShooterImpactEffect* EffectActor = GetWorld()->SpawnActorDeferred<AShooterImpactEffect>(ImpactTemplate, Impact.ImpactPoint, Impact.ImpactNormal.Rotation());
		if (EffectActor)
		{
			EffectActor->SurfaceHit = UseImpact;
			UGameplayStatics::FinishSpawningActor(EffectActor, FTransform(Impact.ImpactNormal.Rotation(), Impact.ImpactPoint));
		}
	}
}