Hey all, so I’m attempting to get the world space position of the bottom right hand corner of my screen and I’ve tried getting the viewport size and then using DeprojectScreenPositionToWorld but it keeps returning world space co-ordinates that are near the middle of the screen. Here is my code:
// Get the Viewport Size
FVector2D ViewportVector = FVector2D(1, 1);
if (GEngine && GEngine->GameViewport)
{
GEngine->GameViewport->GetViewportSize(ViewportVector);
}
FVector Result;
FVector Direction;
APlayerController* PC = Cast<APlayerController>(GetWorld()->GetFirstPlayerController());
PC->DeprojectScreenPositionToWorld(ViewportVector.X, ViewportVector.Y, Result, Direction);
print(Result.ToString());
If you are doing it for ray trace here is how to get TraceStartPosition (world position of mouse pixel) and TraceEndLocation (a ray projected from the start location).
// cannot ray trace without player controller
if (_playerController == nullptr)
{
return;
}
// get mouse position
float mouseX;
float mouseY;
_playerController->GetMousePosition(mouseX, mouseY);
// get current camera location, rotation, direction
FVector cameraLocation = _playerController->PlayerCameraManager->GetCameraLocation();
FRotator cameraRotation = _playerController->PlayerCameraManager->GetCameraRotation();
FVector cameraDirection = cameraRotation.Vector().GetSafeNormal();
// trace start location is the mouse cursor in world coordinates
// trace end location is a ray in the direction of the camera
FVector traceStartLocation;
FVector traceEndLocation;
_playerController->DeprojectScreenPositionToWorld(mouseX, mouseY, traceStartLocation, cameraDirection);
traceEndLocation = traceStartLocation + MAXIMUM_INTERACTION_DISTANCE * cameraDirection;
This code doesn’t seem particularly robust to me.
If I’m next to a wall, this position will project to the other side of that wall. If there’s an interactable in that other room, that interactable would be “visible” to this code.
You need to either do an actual sweep test, or you need to read the depth buffer to get the end location to trace to. Reading depth would introduce a rendering stall, so you’ll generally want to read the depth buffer of the previous frame, which gives a bit of “jiggliness” to how deep you can trace, so a sweep test is usually better.
You might also want to sweep a sphere of some radius, because a ray could get through very small cracks in geometry, and still give access to things that aren’t “in the same room” as the player.
BTW, I’ve seen many ways to do this posted in here. Is there another more minimal code way get the actor and component under a specific pixel given the player’s view and/or mouse position? Also needs the option to ignore certain actors (built into the trace parameters).