ProjectWorldLocationToScreen don't return the same result on different Quality settings

Hi everyone, I got the following code which I’m running in two different Quality settings (resolution scale 100%-25%)

PlayerController->ProjectWorldLocationToScreen(CharacterLocation, CharacterLocation2D);

UE_LOG(YourLog, Warning, TEXT("char location 2d: %s"), *CharacterLocation2D.ToString());

I’m Wondering why this happens and what is the best solution to handle different resolution scales using project and deproject functions.

Thx for reading

Hi Davixe,

ProjectWorldLocationToScreen function returns absolute screen coordinates.
The best solution is translate absolute screen coordinates to relative.

For example:

INT32 width, height;

PlayerController->ProjectWorldLocationToScreen(CharacterLocation, CharacterLocation2D);
PlayerController->GetViewportSize(width, height);

CharacterLocation2D.X /= width;
CharacterLocation2D.Y /= height;

UE_LOG(YourLog, Warning, TEXT("char location 2d: %s"), *CharacterLocation2D.ToString())

In this case you have relative coordinates from 0 to 1 with any screen resolution.

Best,

I tried that code, but is happening the same, with resolution scale 25% on the middle of the screen i get x=0.25 and y=0.25 and with resolution scale 100% i get x=0.5 and y=0.5

Other fact is that the GetMousePosition(MouseX, MouseY) function returns the same value on both settings (0.5).

(I’m trying to trace a line on the screen between the position of mouse and the current character location, so this line is different with the differents scales)

Hi Davixe,
Just want to clarify, how you changed screen resolution (resolution scale)?

In Settings->Engine Scalability Settings-> Resolution scale

22225-resolution+scale.png

Changing the value of resolution scale modifies the return of the ProjectWorldLocationToScreen function.

We added Screen Percentage. Try this:

static const auto CVarScreenPercentage = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.ScreenPercentage"));
  
  INT32 width, height;
  pPC->ProjectWorldLocationToScreen(loc, loc2d);

  float ScreenPercentage = CVarScreenPercentage->GetValueOnGameThread() / 100.f;
  pPC->GetViewportSize(width, height);
  loc2d.X /= width*ScreenPercentage;
  loc2d.Y /= height*ScreenPercentage;

Best,

Ran into this as well in trying to use ViewportToVirtualDesktopPixel.

The problem is that CalcSceneView takes the screen percentage into account, but higher up in the stack the scaling is not reverted before converting from screen fractions into pixels.

While this can be handled like suggested in the case of ProjectWorldLocationToScreen, the same can’t be applied in the case of ViewportToVirtualDesktopPixel as this also shifts the coordinates by the viewport offset.

It’s not broken you’re using the wrong thing.

You’re supposed to use the Project World Location to Widget Position node