Shooting in the direction of the crosshair

The problem is in concept very simple. I have a Crosshair that is displayed slightly below the center of the screen.
I already looked at Adjusting aim direction to crosshair position but the projectiles always go toward the top left portion of the screen.
Now is the tricky part. How to make trace, so it will end exactly at the crosshair position ?

So far I have been using this:

For the HUD location

void ABaseHUD::Get3DCrossHairPos()
{
	//Always Check Pointers
	if (!Canvas) return;

	FVector WorldDirectionOfCrossHair2D;
	Canvas->Deproject(CrossHairCenter, CrossHair3DPos, WorldDirectionOfCrossHair2D);
	PrintDebug(555, FColor::Silver, FString::Printf(TEXT("Crosshair 3D pos: %f %f %f"), CrossHair3DPos.X, CrossHair3DPos.Y, CrossHair3DPos.Z));
	//moves the cursor pos into full 3D, your chosen distance ahead of player
	CrossHair3DPos += WorldDirectionOfCrossHair2D * AIM_DISTANCE;
	PrintDebug(663, FColor::Silver, FString::Printf(TEXT("Crosshair Center: %f %f"), CrossHairCenter.X, CrossHairCenter.Y));
	
}

void ABaseHUD::DrawHUD()
{
	Super::DrawHUD();

	if (CrosshairTexture)
	{
		//Find the center of our canvas.
		FVector2D Center(Canvas->ClipX * 0.5f, Canvas->ClipY * 0.55f);

		//Offset by half of the texture's dimensions so that the center
		//of the texture aligns with the center of the canvas.
		FVector2D CrossHairDrawPosition(Center.X - (CrosshairTexture->GetSurfaceWidth() * 0.5f), Center.Y - (CrosshairTexture->GetSurfaceHeight() * 0.55f));

		//Draw the crosshair at the centerpoint.
		FCanvasTileItem TileItem(CrossHairDrawPosition, CrosshairTexture->Resource, FLinearColor::White);
		TileItem.BlendMode = SE_BLEND_Translucent;
		Canvas->DrawItem(TileItem);

		Get3DCrossHairPos();
	}
}

and for the line trace

void ABaseWeapon::ShootProjectile()
{
 ..........................................
 ..........................................
UCameraComponent* const OwnerCamera = MyPawn->GetFirstPersonCameraComponent();
			
			// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = FP_MuzzleLocation->GetComponentLocation();

			FVector StartPos = OwnerCamera->GetComponentLocation();

			FVector ForwardVector = OwnerCamera->GetForwardVector();
			ABaseHUD* HUD = Cast <ABaseHUD>(Cast <APlayerController>(MyPawn->GetController())->GetHUD());
			ForwardVector = StartPos + (ForwardVector * 20000);
			const FVector End = HUD ? HUD->CrossHair3DPos : (StartPos + (ForwardVector * 20000));
			const FHitResult TargetPos = LineTrace(StartPos, End);
			
			if (TargetPos.bBlockingHit)
			{
				PrintDebug(363, FColor::Silver, TEXT("There was a hit"));
				//Set Spawn Collision Handling Override
				FActorSpawnParameters ActorSpawnParams;

				FRotator SpawnRotation2 = UKismetMathLibrary::FindLookAtRotation(SpawnLocation, TargetPos.ImpactPoint);
				PrintDebug(398, FColor::Silver, FString::Printf(TEXT("Camera Forward: %f %f %f"), ForwardVector.X, ForwardVector.Y, ForwardVector.Z));
				PrintDebug(399, FColor::Silver, FString::Printf(TEXT("Ray Hit pos: %f %f %f"), TargetPos.ImpactPoint.X, TargetPos.ImpactPoint.Y, TargetPos.ImpactPoint.Z));
				World->SpawnActor<ABaseProjectile>(ProjectileClass, SpawnLocation, SpawnRotation2, ActorSpawnParams);
			}
			else
			{
				FActorSpawnParameters ActorSpawnParams;
				World->SpawnActor<ABaseProjectile>(ProjectileClass, SpawnLocation, UKismetMathLibrary::FindLookAtRotation(SpawnLocation, End), ActorSpawnParams);
			}
 ..........................................
}

I have been trying for several hours now without any success, any help/suggestion is welcome.

Hey there, you don’t really need to deproject, if the crosshair is centered you can just get the camera location and forward vector. About the question you asked, do you really need to have a projectile spawned, a line trace is usually better for this. If you still want the projectile then you need to set the gravity scale to 0 so it doesn’t affect the projectile. For the projectile spawn rotation, just set it to the Rotation of the world forward vector of the camera.

You are absolutely right, at first I used a centered crosshair and did what you suggested which worked great but I wanted to have my crosshair slightly below the center of the screen but I could not make it work.

For reference, what I wanted to achieve is this (Halo 3: ODST):

What I got instead is this:

Disregard the “Crosshair 3D pos”, it is actually the crosshair positon multiplied by the range of the weapon.

In that case it might be easier to use deproject.

It did not work because I did not set CrossHairCenter = Center in the DrawHUD method.