Determining proximity to screen center without raytrace

I have a TArray<InteractableObject> of every object the player is physically close enough to interact with, and I’m working on something to run every time the player uses the mouse or movement keys and guess which object the player is trying to use. I know a lot of games require you to look directly at an object to use it, and simply raytrace through the crosshairs and check if you’re looking at an interactable, but instead of checking the exact direction of your gaze, I want to basically assess each item in the array for their proximity to screen center, and return whatever is closest- is there a simple way to accomplish this? One thing I was thinking was to trace a ray, get its vector, then compare the dot product of the centered ray to a vector from screen center to each element of the array, and return which vector most closely matched the ray, but that’s an awful lot of math to do every frame.

You can use Convert World Location to Screen and calculate the distance between to 2D Vectors… and then do some logic to reorder them by distance in a TArray. I did a quick test here and it seems to work.

Ooh thank you, I’m converting this to C++ to test now… do you happen to know if there’s an equivalent to WorldLocationToScreenLocation in the API? I don’t see anything in AActor or UObject.

Yeap. here it is:


APlayerController * PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
FVector2D FinalLocation;
PlayerController->ProjectWorldLocationToScreen(FVector(10.0f, 10.0f, 10.0f), FinalLocation);

PS:
UGameplayStatics comes from #include “Kismet/GameplayStatics.h”

Cheers

Thank you!! In case anyone else needs it, here’s the final version I ended up with. :slight_smile:

APlayerController * PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);	
FVector2D FinalLocation;
FVector2D viewportDimensions;
FVector2D ResultVector;

float ResultLength;
int viewportX;
int viewportY;


PlayerController-&gt;GetViewportSize(viewportX,viewportY);
viewportDimensions = FVector2D(viewportX, viewportY);
PlayerController-&gt;ProjectWorldLocationToScreen(FVector(10.0f, 10.0f, 10.0f), FinalLocation);

ResultVector = viewportDimensions - FinalLocation;
ResultLength = ResultVector.Size();

You’re welcome! I’m glad I helped =)

Just don’t forget to divide viewportDimensions axis by 2 to get screen’s center!

Cheers!

Hmm, so if I wanted to compare proximity to screen center instead of player position, I would just do this?

ResultVector = (viewportDimensions/2) - FinalLocation;

Yes, because viewportDimensions is the size of your viewport (screen size)… so to get the center of it you need just to divide it by 2 =)

the FVector(10.0f, 10.0f, 10.0f) would be the actor world position. It is more clear in the blueprint image that I posted.

Cheers!