Firing a projectile using LineTraceSingle()

I am currently trying to move a blueprint into c++ code that takes the position of where the bullet will be fired from and fires it towards where the player is looking.

My code for shooting is as follows:

void ABaseWeapon::Shoot(FVector Location, FVector ForwardVector, FRotator ControlRotation)
{
	if (RoundsInMagazine > 0)
	{
		//Take one round from the magazine
		RoundsInMagazine--;

		//Line Trace By Channel
		FCollisionQueryParams RV_TraceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, this);
		RV_TraceParams.bTraceComplex = true;
		RV_TraceParams.bTraceAsyncScene = true;
		RV_TraceParams.bReturnPhysicalMaterial = false;

		//Re-initialize hit info
		FHitResult RV_Hit(ForceInit);

		//Calculate tracing range
		FVector EndPoint = Location + (ForwardVector * 10000);

		GetWorld()->LineTraceSingle(
			RV_Hit,
			Location,
			EndPoint,
			ECC_Visibility,
			RV_TraceParams);

		//Did the line trace hit anything?
		if (RV_Hit.bBlockingHit)
		{
			
			FActorSpawnParameters spawnParams;
			spawnParams.bNoCollisionFail = true;
			spawnParams.bNoFail = true;

			//Create spawn location for projectile
			const FVector SpawnLocation = Location + ControlRotation.RotateVector(GunOffset);
			FRotator lookat = (SpawnLocation - RV_Hit.ImpactPoint).Rotation();


			GetWorld()->SpawnActor<UObject>(ProjectileBlueprint->GeneratedClass, SpawnLocation, lookat, spawnParams);
			UE_LOG(LogTemp, Warning, TEXT("Hit"));
		}
		else
		{
			FActorSpawnParameters spawnParams;
			spawnParams.bNoCollisionFail = true;
			spawnParams.bNoFail = true;

			//Create spawn location for projectile
			const FVector SpawnLocation = Location + ControlRotation.RotateVector(GunOffset);

			GetWorld()->SpawnActor<UObject>(ProjectileBlueprint->GeneratedClass, SpawnLocation, ControlRotation, spawnParams);
			UE_LOG(LogTemp, Warning, TEXT("No Hit"));
		}
	}
}

It seems to be logging correctly when I am pointing at something it should hit but I am seeing no projectile being spawned. When I do not get a hit result the projectile fires in the default direction that ends up parallel with the reticule in the centre of the screen.

I believe I am going wrong here:

FRotator lookat = (SpawnLocation - RV_Hit.ImpactPoint).Rotation();


			GetWorld()->SpawnActor<UObject>(ProjectileBlueprint->GeneratedClass, SpawnLocation, lookat, spawnParams);

Thanks for any assistance. :slight_smile:

tl;dr: I want my projectile to fire towards the location that LineTraceSingle() hits against.

EDIT: Also going to add an illustration of what I am wanting to do:

Your SpawnLocation takes into account GunOffset while your linetrace does not. Also, a line trace does not take gravity into account while a projectile does…

Why don’t you just use the projectile and use the OnComponentHit notification hook?

The first person c++ project has a good example of this…

I’ve added an illustration to the original question to better explain what I am wanting to do. The line trace needs to start at the player as it will be the centre of the screen.

It looks like your projectile doesn’t respect gravity. Does your projectile class have a UProjectileMovementComponent ?

Yes it has a projectile movement component.
The projectile is fired correctly and when this method is done in blueprints it gets the expected results. My issue is translating that blueprint into c++.

in the blueprint implementation are you using FindLookAtRotation function?? if that the case in cpp the similar implementation would be FRotationMatrix::MakeFromX( [targetLocation] - [originLocation] ).Rotator.

It had 2 problems one of which you helped me solve. The code I have now is:

//Create spawn location for projectile
			const FVector SpawnLocation = Location + ControlRotation.RotateVector(GunOffset);
			FRotator lookat = (RV_Hit.ImpactPoint - SpawnLocation).Rotation();

			GetWorld()->SpawnActor<UObject>(ProjectileBlueprint->GeneratedClass, SpawnLocation, lookat, spawnParams);

That gets me the correct look at rotation. My other problem was that I was passing the function the player world location and not the camera world location which is what made the line trace work in blueprint.

Thanks for making me look at my own code harder. :stuck_out_tongue:

I believe you can get the camera location, for example. Just get the actor and get the camera component, (never tried ot before tho…) but also i think it’s quite not a right implementation if we had to down so low to the camera position… jejeje. Are you’ve been trying to play with the control rotation, etc??