I recently upgraded to UE5, and spent some time putting together a minimal working UI using the new CommonUI plugin. (I’ve also looked at Lyra, but I was curious how much work it takes to build something from the ground up, without Lyra’s extensions).
I added one master Widget to the player’s viewport: this Widget contains two “layer” Widgets in an Overlay, which are basically just UCommonActivatableWidgets that contain a UCommonActivatableWidgetStack.
The first layer automatically activates a screen with a Forward button, which transitions to a second screen with a Back button. The second layer contains a message box with an OK button, which can be activated at any time. It pops up in front of the first layer and prevents any input to it until dismissed. Each of these buttons has a TriggeredInputAction assigned.
Overall, very impressed with the direction that CommonUI is taking, some of its features have been sorely missed until now. But as one might expect from an experimental plugin, there are also some teething issues I’ve run into, which I’m gonna list here in no particular order:
-
ButtonStyles have brushes defined for Normal, Hovered, and Pressed states, but text styles are for Normal and Hovered only. This leads to inconsistent behavior between the brush and the text when the user presses the button, then drags the cursor off of it. I worked around this by defining a second ButtonStyle for the Pressed state with a third TextStyle, and switching between the two ButtonStyles on Press/Release.
-
UCommonActivatableWidgetContainerBase would really benefit from events when transitions begin and end. I had to resort to using my master Widget’s Tick to continuously poll if the messagebox layer still had a valid ActiveWidget, to see if the regular layer is ready to reactivate.
-
The built-in transitions in UCommonActivatableWidgetContainerBase are very convenient, but it would also be nice if there was a hook for the contained Widgets to provide their own animations for the transition. Also, can we have different transitions for the outgoing and incoming Widgets please.
-
Still on UCommonActivatableWidgetContainerBase: when transitioning to a new Widget, it would probably be a good idea to withhold the call to ActivateWidget() until the transition has completed, to avoid receiving input too early. Imagine a confirmation messagebox that performs some important action, with a fade-in animation. You probably don’t want to let players perform said important action before the messagebox has fully finished fading in.
-
I thought of rolling my own implementation of UCommonActivatableWidgetContainerBase to make the above changes, but sadly none of its functions related to transitions are virtual. If the default behaviors aren’t going to change, can we at least have a way to provide our own overrides?
-
From what I’ve seen, multiple ActivatableWidgets inside an Overlay seem to have contradictory behaviors regarding rendering vs input. Widgets at the top of the list in the Overlay’s children are rendered below their subsequent siblings, but they receive InputActions before them. Arguably, one should author their Widgets to be more explicit in their input routing, but I feel like it’s also a reasonable expectation that, all else being equal, Widgets rendered on top should also get dibs on handling input.
-
The Common UI Quickstart Guide says to define InputActions via CommonInputActionDataBase DataTables. However, several comments in code allude to this system being deprecated in favor of EnhancedInputActions. Is this true, and if so, can you please make a note of this on the documentation page?
-
I found no way to tell a UCommonActivatableWidget to listen to an arbitrary InputAction, at least from Blueprint. Is this by design? I worked around this by putting a button with 0 scale in my master Widget, so that it can trigger the activation of the messagebox layer.
Hopefully you found this wall of text useful. Really excited to see where this plugin is going!