How can I get screen coordinates from world coordinates?

I am teleporting my character with a button press to my cursor, but only in a certain radius. Therefore if my cursor is further away from the set radius I teleport my character in the direction of the cursor, but only on the circumference of the circle (the furthest distance => maximum radius).

To get the actual position of the cursor I am using the GetHitResultUnderCursor(...) function. My problem with this is, that if my cursor is out of range, then the actual hit result might be wrong in Z direction, hence after I recalculate the position as I mentioned above my character might be falling after the teleport, since it will teleport above the ground. This can happen for example if my cursor is out of range and is on top of an object which is higher then my character. Hope this makes sense, little bit hard to explain. So X and Y directions are always correct only Z needs to be recalculated.

My idea was that after I recalculate the position on the circumference of the circle I some how project that world coordinate to screen coordinate and then try to do a new hit result at that point so my Z coordinate gets “fixed”. This is how I did it (I am really new to UE4, so this might be really wrong):

UCanvas* canvas = (UCanvas*)StaticConstructObject(UCanvas::StaticClass());
FVector toScreen = canvas->Project(newPos); // newPos is the FVector position on the circumference of the circle
FVector2D screenPos = FVector2D(toScreen.X, toScreen.Y);
                    
GetHitResultAtScreenPosition(screenPos, ECC_Visibility, false, Hit);
newPos = Hit.ImpactPoint;
newPos.Z += Pawn->GetDefaultHalfHeight(); // translate character from (0,0,0) so it stands on its feet

The thing is that I am getting 0, 0 every time in screenPos for X and Y. Anybody could help me or give me some hint how to do this properly? Thanks in advance!

Hi Silex. Take a look at this question. It seems to be somewhat similar to what you are trying to do, and the solution might work for you as well.

Hello ! Actually I am using that function which is suggested by the post you posted. The reason why it didn’t work for me is because I was trying to use it outside of the DrawHUD function in my PlayerController class. Here is the post which showed me what I am doing wrong.

Also I managed to solve this problem without the Project(...) function, thanks to this post. The code what I used from there is this:

FVector2D FRTSHelpers::Project(FVector WorldPosition, ULocalPlayer* Player)
{
	FVector2D retVal = FVector2D::ZeroVector;
	if (Player != NULL && Player->ViewportClient != NULL && Player->ViewportClient->Viewport != NULL && Player->PlayerController != NULL)
	{
		FSceneViewProjectionData ProjectionData;
		if (Player->GetProjectionData(Player->ViewportClient->Viewport, eSSP_FULL, /*out*/ ProjectionData))
		{
			FMatrix viewProjectionMatrix = ProjectionData.ViewMatrix * ProjectionData.ProjectionMatrix;
			FIntRect theViewRect = ProjectionData.GetViewRect();

			FPlane Result = viewProjectionMatrix.TransformFVector4(FVector4(WorldPosition, 1));

			retVal.X = (int)((((1 + (Result.X / Result.W)) / 2.f) * theViewRect.Width()) + 0.5f);
			retVal.Y = (int)((((1 - (Result.Y / Result.W)) / 2.f) * theViewRect.Height()) + 0.5f);
		}
	}
	return retVal;
}