I'm not sure exactly how you want it to work, but if you don't want to change your shooting direction, you will have to constantly do a trace in your aim direction (this will get complicated if your projectile has gravity applied) until you find a hit, then reproject that world location back to the screen, get the 2D coordinates and draw your crosshair at that location. Be aware that your crosshair will jump around on the screen as you're effectively introducing a depth parameter. You can have a look at GameplayStatics::ProjectWorldToScreen(...).
Update: Here's some code.
// Declare some required params
const float traceDistance = 5000.f;
const bool drawDebugLine = true;
const float calibarionDistance = 3000.f;
const float projectileSpeed = 4000.f;
// Get ViewRotation & Viewpoint
// I don't know what your setup is but I'm using a custom camera. You require the current world rotation of the active camera. You could try "Cast<APlayerController>(Controller)->PlayerCameraManager->GetCameraRotation().Vector()"
FVector viewDir = Camera->GetComponentRotation().Vector();
// I don't know what your setup is. I'm using a custom camera, but you require the center of the screen's world location. You could try "Cast<APlayerController>(Controller)->PlayerCameraManager->GetCameraLocation();"
FVector traceStart = Camera->GetComponentLocation();
FVector traceEnd = traceStart + viewDir * traceDistance;
// Set up trace params
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
// Trace from center of screen in direction of aim
ECC_Visibility, //collision channel
// Requires include: #include "Runtime/Engine/Public/DrawDebugHelpers.h"
DrawDebugLine(GetWorld(), traceStart, traceEnd, FColor::Green, true);
// Get the muzzle location
FVector muzzleLoc = CurrentWeapon->WeaponMesh->GetSocketLocation("MF");
// The required direction of the projectile
// If we've hit something with the trace, let's send the projectile there.
locationToSendProjectileTo = RV_Hit.ImpactPoint;
// Otherwise we use a "calibration distance". The distance from us at which the bullet should intersect the crosshair line
locationToSendProjectileTo = traceStart + viewDir * calibarionDistance;
// Calculate bullet velocity
FVector bulletVelocity = locationToSendProjectileTo - muzzleLoc;
bulletVelocity *= projectileSpeed;
// Draw debug line to show where bullet will go
DrawDebugLine(GetWorld(), muzzleLoc, locationToSendProjectileTo, FColor::Red, true);
// Spawn projectile at muzzle location and set its velocity...
Oct 19 '17 at 02:38 PM