What is the best way to get size of widget in viewport?

Hello!

What is the best way to get size of widget in viewport? Currently I’m using MyGeometry.GetLocalSize() in Tick event in Blueprints. But it’s not convenient way, because sometimes widget A wants to know local size of widget B (for example, I had this situation when I was realizing custom ScrollBox).

Dima.

good question

1 Like

These days it’s pretty straightforward:

213801-untitled.png

That’s unless we’re talking about a more specific situation.

I know this is an old question but it is among the first results in google and it’s not answered so the answer is you need to get the cached geometry and either get the local size or the absolute size.

The absolute size will get you the size based on the the window resolution so you’d get dynamic results based on your current resolution while local size will get you the local size in local space, try both and see which one you want to use.

There’s one thing that is very important to keep in mind, you will get (0, 0) if the widget is not in viewport or if you instantly try to get this value right after adding the widget to the viewport, so you just added the widget to the viewport you need to wait a few milliseconds before you can retrieve the size, you can do a loop+delay until size > 0.

3 Likes

so you just added the widget to the
viewport you need to wait a few
milliseconds before you can retrieve
the size

That’s what Force Layout Prepass is for. Otherwise you’re getting stale data. Or data that’s not ready.

Thank you I didn’t know that, pretty useful however it doesn’t work for Cached Geometry only for desired size at least according to my test.

All it does is forces the widget to Tick early and update, should work in theory but I’ll take your word for it.

Are you calling it before pulling the cached geo data?

Yes I’m calling Force Layout Prepass then getting the cached geometry, the result is (0,0) but for desired size it’s working properly, maybe the cached geo is set after the widget fully rendered or something I don’t know let me know if you found something.

Yes, At times, Cached Geometry may not be up-to-date. You can determine whether Cached Geometry is up-to-date or not with the following function:

TakeWidget()->NeedsPrepass()

Using this function, you can wait until Cached Geometry is updated and then proceed with further tasks.

void UMyUserWidget::DoSomething()
{
	auto& timerManager = GetWorld()->GetTimerManager();
	timerManager.ClearTimer(translateMapHandle_/*this is member variable*/);
	if (TakeWidget()->NeedsPrepass())
	{
		translateMapHandle_ = timerManager.SetTimerForNextTick([this]()
		{
			DoSomething();
		});
		return;
	}
	// DoSomething with GetCachedGeometry()!
}

I hope my response proves helpful! :slight_smile:

1 Like

This works perfectly for me when run in the editor, however at runtime on 3D widgets It returns incorrect values.

The X value is correct, but the Y matches the desired height of a the component when it was first setup in the editor and not it’s height when layout has been applied once instantiated into another widget.