Widget component Draw Size X or Y can't be rendered greater than 16384 (2^14)

Hi,

I was trying to increase the size of an Actor with a Widget Component (also called 3D Widget by the community) and noticed that the Widget Component can’t be rendered to its real size if the X or Y value of the Draw Size is greater than 16384, i.e. 2^14 (if set to 16385, for example, it will keep its previous appearance without processing the new value).

It’s worth noting that the widget actually exists with its new size even if going beyond 16384 (it can be clicked with a Widget Interaction component of a Player Controller, for example), but it isn’t visible to its whole extent.

This behavior has been seen in 4.16 and 4.18 (not tested in other versions), in Editor, PIE and Standalone. When an Actor with a Widget Component is in a Level, this behavior can be seen both when manually adjusting the Widget Component’s Draw Size using the Details tab of the Editor and when editing the Draw Size via Blueprint scripting at runtime.

Repro steps:

  1. Create a Blueprint Actor with a Root Component and a child Widget Component (skip this if you already have an Actor like this to test). Set the Widget Class of the Widget Component to be a Widget Blueprint you have. If you don’t have one, you can test with one like the following: a Widget Blueprint with an Overlay as its main Widget and a Button as its child Widget (for convenience set the Button’s Horizontal Alignment to "“Horizontally Align Fill” and Vertical Alignment to “Vertically Align Fill”). For convenience, in the Actor Blueprint, set the Widget Component’s Pivot Point to be (0, 0). Notice that by default Draw Size is (500, 500), keep that for now.
  2. Place the Actor in a Level so you can see it.
  3. Change Draw Size X or Y for the Actor’s Widget Component. You will notice that as long as you stay below the 16384 value it will visually update as expected, but not when the value is higher (it won’t render a greater version of the Widget).

Expected behavior: The Widget Component should have its visual size updated to the Draw Size even when Draw Size X or Y is greater than 16384.

It would be great to know about existing fixes or workarounds to get the Widget Component to render correctly, if you know any, or otherwise see this acknowledged as a bug to be solved in future realeases of the Engine.

By now, as far as I know, it seems to be no way to have a Widget with physical presence in the world (not simply in the screen) to be greater in size than (16384, 16384). Scaling the whole Actor or the Component with traditional Scale is not a good solution if one of the extents of the Draw Size is much greater than the other one, since it looks bad.

Thank you.

Out of sheer curiosity, why would you ever need a widget with that size?

Hi Everynone,

There a some contexts in which a physical actor may need to have a widget attached to it, following its location (e.g. health bar on top of it or some button-like element that can be clicked to produce some interaction). If the actor is very big (think of a big spaceship for example), the widget draw size should be very big as well to match its size (just increasing the scale can cause to have a bad looking widget). The widget could of course be replaced with a mesh with some interaction enabled (e.g. clicking if needed), but it might not be as visually suitable as a widget (depending on the function it has, like one of the previously mentioned ones).

Honest question: Why wouldn’t you use a normal widget for this instead? As in, why not use screen space?

You can use canvases as UI layers to easily control many widgets at once with each widget having its own Z order in each layer. This grants you more flexibility that any component will ever give you. Not to mention performance gains. In case you worry about widgets lagging while tracking their targets, you can change the responsible actor’s Tick to PostUpdateWork - this makes it super snappy.

In case it must be a widget component, you can always use it in screen space. This removes all the scaling issues from the equation, gives you full control over its size and position. It also makes it look sharper. Not sure whether the render order is preserved correctly, most likely ‘yes’ but don’t quote me on this one. :wink:

The only thing that pops for me that could ever need a widget scale this big is a VR setup where normal widgets just won’t cut it. Still there are target renders and workarounds there as well.

Not trying to argue whether the clearly hardcoded 16384 limit is there for a reason. Just talking from my own experience of working with widgets and cosmos-like distances (where you end up faking 95% of everything that has something to do with large distances because of float precision errors and the need to shift the world origin anyway)

TL;DR: consider using regular widgets to present actor metrics to the player. See how it pans out. Even if Epic decides to lift the scale limitation here, you’d need to wait 6-12 months before you see it implemented. If ever. Just saying :slight_smile:

Thank you for the detailed comment, Everynone. I’m trying to figure out how would I be able to use regular widgets instead of widget components in my current context, or screen space instead of world space if staying with widget components, so I’ll share some more details of what I’m trying to achieve.

I have an actor that is always facing the camera (so no trouble with rotation conversions) but might be visible or not, since the camera might be looking somewhere else. There’s the need to display a clickable widget on top of the actor, so it can be clicked to interact with the actor. For consistency it’s required that the size of the widget is always kept the same as its owning actor, i.e. it’s very important that they occupy the same amount of space, one in top of the other.

I think that placing the widget on a screen position that matches its owning actor’s world location would be feasible with some of the engine’s projecting/deprojecting functions. It is the very specific requirement of the widget having the same exact size as its owning actor what seems more tricky to do if not using world space for the widget component or using a 2D widget.

Do you think that using either 2D widgets or widget components with screen space instead of world space is still feasible for this scenario? If so, I would find it very helpful if you wished to give some insight on how to go that way.

There’s the need to display a
clickable widget on top of the actor,
so it can be clicked to interact with
the actor. For consistency it’s
required that the size of the widget
is always kept the same as its owning
actor, i.e. it’s very important that
they occupy the same amount of space,
one in top of the other.

That’s super clear. Explains why you want to stick to the widget component.

One thing I do not get is a situation where an object is so far away that it occupies just a handful of pixels on the screen. Trying to click the UI element that small would be user unfriendly.

I think that placing the widget on a
screen position that matches its
owning actor’s world location would be
feasible with some of the engine’s
projecting/deprojecting functions.

This part is straighforward, indeed.

It is the very specific requirement of
the widget having the same exact size
as its owning actor what seems more
tricky to do if not using world space
for the widget component or using a 2D
widget.

If the object getting very small is not an issue you can MapRange widget size based on distance between the owning actor and the camera. I was translating distance into widget opacity and Z order to have distant UI elements fade away; it worked well with hundreds on-screen icons at a time.

Do you think that using either 2D
widgets or widget components with
screen space instead of world space is
still feasible for this scenario? If
so, I would find it very helpful if
you wished to give some insight on how
to go that way.

I’m assuming there is no text involved here. Text scaling looks bad most of the time. You’d need to try both methods and see where it takes you. I abandoned widget components (back when they were still called 3d widgets) since they did not suit what I was attempting. Try both.

Thank you for the insight, Everynone. I’ll stick to the widget component but change to screen space to cope with the world space’s draw size limit, positioning the widget with the projection/deprojection functions and scaling its size based on the distance to the camera. The MapRange function is indeed a good idea to transform size based on distance, but I think I’ll possibly end up coding a non-linear range conversion function that takes into account the math aspects of the perspective camera (angle, aspect radio) for greater precission.