UMG world to screen space vs resolution.

I’ve tried this in both 4.6.1 using the playercontroller worldposition to sceenspace as well as 4.7 with the screen space option in a blueprint with a widget component. If the screen resolution (r.setres XxY) doesnt match the window size, the widget position will be incorrect. The effect can only be seen in fullscreen since r.setres in windowed resizes the viewport. Here is the result, first picture is 1280x720 windowed second is 1280x720 fullscreen on a 2560x1440 native res panel.

Hello ,

After looking over your issue I believe I have a workaround for you. Right now there is an issue with widget assuming that the screen size is 1920x1080 and so it reads the resolution give to it as though it were being used on a viewport of 1920x1080. I have a formula that will allow you to get an accurate position. I hope that this helps.

Here is the formula that can be used to set the position of your widgets. PLEASE NOTE: this requires the original position of the widget to be 0,0 and it must be anchored to the top left corner of the screen. The rest of the notes are listed in the picture. This was all done in the event graph of the widget.

Here is an example of what it looks like when I had finished. My widget size in this example is 70 by 70.

How the math works:

1920 x 1080 is divided by the actual view port size (X and Y receptively). This then give a ratio of what the widget thinks the screen size is versus what the actual screen size is. (Example: Let’s say the viewport size is actually 960x540. Which means 1920/960 = 2 and 1080/540 = 2. This makes the ratio for your X is 2 and your Y is 2. this means for every point of resolution you set your widget by on the actual size of the screen it will think that it has moved 2.) Now that you have your ratio you are going to multiply that but the screen position you would like to have the widget displayed at. (Using the same example: Lets say you want the widget at 100 by 100 this will need to be multiplied but the ratio (2 in this example) make it 1002 = 200 and 1002 = 200. The 100 is the actual position and the 200 is what the widget thinks it’s at. This will fool it in to placing it in the right spot.) After this you will want to set he position of the widget using the anchor points. I have found this to be the most accurate way to set the positions using this method. To do this you will need to understand that anchor positions go from 0,0 to 1,1 in respect to X and Y. To get this you will need to divide the current formulated position of the widget by the maximum viewport size (this will give you a percentage of sorts (mean that 1 in this case means 100% of the screen size and 0 being well 0%) and allow you to set the position of the anchor).

Make it a great day

Thanks for the reply! I’m not sure if something isn’t working with my editor because get viewport size doesn’t return the resolution of the screen but the size of the viewport. For example if you try running in any play mode (PIE, new window, standalone) and even if its in windowed mode, if you set either r.screenPercentage 50 or if in fullscreen r.setres (something other than native) it will be offset incorrectly. I my case I have the return of getViewportSize printing to screen for debugging and it doesnt change when setting those console variables.

I also want to point out that I built the same setup shown in your example and it only positions the widget correctly if the Viewport is 1920x1080.
Here is my blueprint: My image is 100x100

I would also like to add that before, I had the widget not have a canvas panel as the root but instead used SetPositionInViewport with the result of worldPositionToScreen. This worked with all resolutions, but it would break if the rendering resolution did not match the size of the window.

Hello ,

I see that you are using the Get viewport size from the player controller. This returns the size of the HUD canvas. Are you making any alterations to the size of the HUD canvas? The reason I as is because when I change the screen resolution I am having no issues other than the image offset being a little off. But I compensated for this by simply dividing the half size of the widget by the screen ratio.

Change:

Here is my Designer tab in case there is any confusion.

Thank you for continuing dedication to this problem though it still doesn’t seem to be working for me. I took a video of the problem I’m trying to describe as well as you can see my blueprint below. The problem seems to be that it is placing the widget based on the rendering resolution rather than the viewport size. I cant find any way to read the rendering resolution. I event tried to go C++ with GEngine->UserSettings->GetResolution() I think (I cant remember the exact code I tried).

Here is the video I took: - YouTube

Hello ,

I was able to reproduce this issue. I realized the issue only happens in fullscreen. There is a workaround. Instead of manually putting in the console commands I would suggest having the user select from a pre-made list and then use the “Execute console command” node to set the resolution. This will give you the benefit of knowing what resolution will be applied. You could then set the “Make vector 2D” node to what ever resolution is being applied.

Example:

I’ve thought of that solution. To be honest it’s not the biggest problem and it’s rather a special edge case scenario. Do you know if there is any way of getting the current 3D resolution? A C++ solution is fine. The GEngine->GameUserSettings->GetResolution() only returns the last confirmed resolution (doesnt change with r.setres)

Hello ,

If you are looking for a solution in code, you will need to use ScreenPositionInvDPI. ScreenPositionInvDPI: The position in the viewport with the inverse DPI applied to it. This is useful for positioning child widgets of widgets in the viewport where you need to remove DPI before applying it. I hope that this helps.

I had a similar problem while trying to get a crosshair system to work, and I found an excellent solution in a forum post.

Long story short, multiply the screen location coordinates by the inverse of the viewport scale.

https://forums.unrealengine.com/attachment.php?attachmentid=34771&d=1428854684

(Yes, this question is over 2 years old, but I hope this answer helps someone searching around.)

Wow, this REALLY works as intended, AND it’s easy to integrate!
I just divided the scale instead of using power -1, which is basically the same thing

there’s a function called Project World Location to Widget Position, which I think is what should be used now.