I am currently working on a strategy game where the player has a number of buttons available on the user interface to construct buildings. These buildings are categorized into submenu’s, which I have implemented as widgets of MenuAnchors that are opened and closed when the category button is pressed.
Additionally, the player may pause the game at any point. The pause menu has a background blur that covers the entire screen. Most buttons of the construction menu are also properly hidden, expect those widgets that are added to the viewport by the menu anchor. It seems those always render on top no matter what Z-Order I put in when adding the pause widget to the viewport. I am absolutely sure that the pause screen is the last thing to be added to the viewport.
Thanks for taking the time to respond! The widgets are indeed in different widget blueprints. All the widgets are added from a custom PlayerController class. When I call AddToViewport on the widget, it does not matter what I pass in for the Z-order, it will still poke through. The only difference with any of the other widgets is the fact that it is opened by a menu anchor. In fact, the blurred out content in white right next to the circled button is in the same blueprint as the button that is poking through, so I would assume the layering is correct. I’m confident that the Pause widget is added to the viewport last in any case so I would expect everything to be blurred out.
To correctly layer widgets, you should make one full-screen layout widget, which you then add the other widgets to; this will let you control the Z order of them individually. Adding multiple widgets to the top level of the screen makes it hard to control.
Hmm, can you have a “full screen layout widget” and still add different HUD blueprints to it?
Previous projects we had a single monolithic HUD for each GameMode but the blueprints and the code classes became so bloated. Now we split out each logical part of the HUD to its own UserWidget blueprint and class. Separating them out is nice for testing new parts of the HUD or getting new devs up to speed on the HUD without fear of breaking core HUD functionality.
So for example above the Mouse HUD widget gets added in Level Blueprint on BeginPlay() with the z-order being very high because it is the mouse cursors / tooltips.
There’s no real difference between a “HUD” widget and any other widget. If you need to Z-order your individual widgets correctly, you can make your “HUD” (that’s added to the player screen) be a dumb Canvas container, with functions to plug in each of the components, which are just blueprint Widgets in their own right. That container can then make determinations about how to Z-order them, if it needs to.
In general, Z order only applies to direct siblings – “cousins” do not by themselves see each other’s Z order, but instead sort entirely based on their shared containers. The mental model I have for this is: “A container draws all its children. It draws them by sorting them by Z order, and drawing them in that order. When each child gets drawn, IT sorts ITS children in Z order, and draws them, recursively.”
Thanks for the insights! I spent the past few days reworking my widgets to see if I could get the ordering right that way, but even if I add all of my widgets as direct siblings of a single layout widget, a menu anchor will disregard ordering the always render on top.
I have since replaced by menu anchor with a vertical box to replicate a combo box effect. This does get blurred out the way I expect. If I have some time in the next few days, I will try to replicate the issue in a clean project.
Having the exact same issue with menu anchor elements being rendered on top of my pause menu although the pause menu is added to the viewport last. This has to be fixed please!
It’s expected behavior. The menu anchor uses deferred painting, meaning regardless of initial Z order it will be painted on top of everything else. It’s a bad practice to use that as well. As far as I know, it’s even the only widget in the engine with that ability.
I know, because I implemented my own Slate widget to use that same ability for an improved UMG based software cursor alternative, since cursors are the only widgets that should always be rendered on top.
Advise is not to use the menu anchor, or use centralized management for your UI so that you can easily close a menu containing the menu anchor while opening a menu “on top”.