get a widget's location in screenspace

Does anyone know a way to get the location of a widget in screenspace?

I’ve got a bunch of buttons that spawn into a scrollbox, and I want to pop a contextual menu up on the location of each button when pressed. The only function I see i that looks like the correct one is getting the widget transform, but it appears to spit out 0,0 for every item within the scrollbox. I’m guessing it’s because it’s outputting it’s own transform relative to itself, which seems correct as 0,0.

Getting the slot from the scrollbox doesn’t seem to work either… I don’t see any functions related to transform, viewport, screen, or anything when getting a slot. Same with the render transform when I get a child of the scrollbox… it’s always 0,0.

Any help or guidance would be appreciated. I’m attaching an image to better illustrate what I’m trying to accomplish.

8537b54a8292419cdd8fa6b56a69a62340cfb04e.jpeg

Screenspace location is only known in events that have blue geometry node in UMG.

If you drag from it there are some nodes in context list.

I do not remember exactly now, but i think those events are on construct and on draw in event graph of umg hud. This thing is also quite complicated, or undocumented, or just messy.
(I am not sure yet which one is the case here).

And be careful because input coordinates (from mouse or touch) are different from world space (calculated as world to umg coordinates), and umg space, so you have 3 differently scaled areas (also different aspect ratios).

Thanks! Good to know. Looks like I’ll need to put it on tick, since I there aren’t any other events that I can use that’ll work with controller & mouse/keyboard.

Hello,
You can use “set position in viewport” to set location of a widget in viewport (don’t forget to set z order higher than main widget).

2 Likes

All mouse and keyboard events send the geometry of the widget.

Yeah, the problem is that I’m manually setting focus on widgets in a scroll box using an index since I need controller input. The buttons never get hovered or mouse events, they just get their properties set based on manually managing what should have focus.

I think the focus event also sends geometry.

Can anyone please answer this question with a very simple example?

is there a way to do this line of thought:
i need to move an object i just created to buttonX.viewportLocation + (x,y)

It’s not simple. Slate does not allow access to widget geometry outside of the event/layout pass where the geometry is stable and you can make the correct calculations without introducing layout loops. The only widget who gives you access to their geometry is your own, during the Tick or the events where the geometry is available.

1 Like

This is what I’ve been playing around with. For now I’m just outputting to a print string. I’d assume that converting 0,0 in the geometry from local to absolute would return the upper left corner of the widget in screen space. My test case has a widget embedded in a border, and the tick->geometry check is being performed by the widget within the border.

That value should be 124,124 in my test scenario. The value I’m getting is 433,284, which is the location of the yellow circle in the attached image. I can manually mess with values from that to push that dot back to the location I want via trial and error, but if I could figure out how those values are created, I could probably come up with something more reliable. I’m obviously misunderstanding something here… but I can’t figure out what.

localOffset.png

Ok… so it looks like the values it outputs assumes a 1080p resolution. When I full screen and test at 1080p, I get the values I would expect. I guess I need to multiply the output values against the resolution scale of the current UI.

Now to find where that’s stored.

The absolute coordinate is in desktop space that’s why it works in fullscreen. You’d need remove the viewport’s inverse transform, to get it in viewport space. Though I don’t know if that transform is readily available.

I’ve added some utility functions to ML to help with this in the future, if you want to grab the code and throw it into your own utility BP library, here’s the changelist.

https://github.com/EpicGames/UnrealEngine/commit/56a1390541ffead1fc33a7aefe809abdc9f17e77

The functions will give you the position in both viewport space and screen space. viewport is like pre DPI scaling space of widgets. Screen is, canvas land, pixels, ray casting land…etc.

To revive an ancient thread, I’m now doing this using the Menu Anchor system. It seems to be working well and addresses my issue.

To revive an ancient reply to revive an ancient thread, how did you get the menu anchor to appear over an item that is outside the UI (player etc)?

To revive an ancient reply to revive an ancient thread reply used to revive an ancient thread, how did you revive an ancient thread like this ?

Hey, stuck bug, did you use a scroll box or a list view in the widget? Also, how can you get the list view to display?

Decided to answer this since this is the first post that pops up in google and it still hasn’t been answered.

8 Likes

What are you using to feed the “Widget Position”?

4 Likes

Solutions posted here didn’t help me, so I’ve decided to revive this thread for anyone finiding it, looking for an answer (like me, recently).

In my case I wanted to create a widget in a position of another widget, but it should also work with moving widget around.

First of all, this is the post that helped me

And this is my implementation:

20 Likes