Download

Would having 'Event Added/Removed' for UMG widgets be useful for you? (including pull request)

One feature that I’ve wanted for a while is UMG widget events that fire when the widget is added to or removed from the viewport or another widget. You could compare this to the actor’s BeginPlay/EndPlay events: I use EndPlay often to cleanup objects that I created or events I bound at BeginPlay. Something similar for widgets would be really useful in my opinion. I’m curious if others out there are interested in such a feature. If you are, good news: I’ve got this working and have created a pull request on Github. Please leave a comment there to indicate general interest in this feature.

Pull request on GitHub

The idea is not only to allow widgets to respond to them being added/removed via Event Added/Removed, but also to let actors respond to a specific widget being added or removed by binding events to OnAdd/OnRemove delegates on the widget. Take this situation: an actor creates a widget and updates the information displayed on it every Tick. If the widget has a way to be removed outside of the actor’s influence (for example it can be closed by clicking a close button), it would be useful if the actor has a way to be notified of this so he can stop updating the widget.

Here is how using the events and delegates looks in blueprint.

This PlayerController reacts to the ParentWidget being shown and hidden.
35e6403d503bb3109ea9d7a0ebfba23836e638fa.png

This ParentWidget reacts to itself being shown and hidden, and to its own created children being shown and hidden.
52c73f6aa6d0dd3abcdcadf5df286dcc380f19cd.png

This ChildWidget reacts to itself being shown and hidden.
2af2a2b916c0aa77ff377adf4f6b6bbeb6eaf492.png

And here it is in action:

So what do you guys think? Would this be a useful to you?

I can see situations in which this would be useful.

You’re going to need to continue to think about this some more, can’t take it in the current form. This doesn’t solve adding UMG widgets to the viewport or other existing slate widgets through native code; this only solves triggering it when adding to other UMG panels.

Hey Nick,

Thanks for taking the time to look at it. In its current state the events take into account these cases both when called from C++ and BP:

  • AddToViewport and AddToPlayerScreen called on the widget itself
  • RemoveFromParent called on the widget itself
  • When added or removed from any UMG PanelWidget: Canvas, VerticalBox, HorizontalBox, Overlay, etc

You mention that I missed the case of adding a UMG widget to an existing slate widget, could you point out which slate C++ classes/functions are involved? I’m mostly familiar with using UMG for in-game HUDs, I’m not very familiar with slate. Do people use UMG and slate used together for in-game purposes or is it an either/or situation most of the time?

What do you think in general of the idea of having native added/removed events? I’ve also considered an alternative to this: events/delegates that fire when the user widget changes visiblity, this would include being removed from screen as part of a parent, but to get that working would require taking more cases into account and I’m not sure if its worth the computational overhead. That’s why I’m really interested in whether more people have been wanting UMG added/removed events or visibility change events.

Ah I missed the change to Add/Remove from viewport/parent in user widget - I stand corrected, at the UMG level this looks like it works for basic widgets. EDIT: Though, I think this wont cover the widgets that generate children - e.g. String ComboBox, ListView, TileView…etc.

Yeah - all our internal games use some level of mix between Slate and UMG - I imagine that’s mirrored across other studios. Sadly, I can’t really point to a location where this happens in Slate, it’s not as centralized as it is in UMG. We’ve talked about adding a concept of parent pointers to slate, if we ever manage to introduce that, it would give us the central location to add this functionality. Because where ever you need to update the parent pointer, you could also add an event for Parent change or something.

I think the idea can be useful, there’s even a feature in the backlog for this for UMG - though we’ve managed to create the editor and never needed it in Slate. I’ve prototyped UIs before where I’ve wanted to trigger some code after adding UI to the screen or some other place where I know the widget tree is stable. However what I usually find myself doing is making the parent widget do the work. So normally you just don’t add a widget to the parent, normally you add it, maybe adjust slot options, maybe set a viewmodel/data model object…etc. So adding to the parent isn’t normally the trigger I care about, if that was the last thing that happened maybe, but most times I end up having to just make an interface or a function that’s “Initialize” and just call that from the parent after I’ve configured the child.

So I’m conflicted on it, on one hand it adds something people have asked for, on another, it may not be what they actually need in the end. I think it’s worth considering, will continue to think it over - I’m eager to see what others using UMG think as well.

No problem, I’m glad I got that part right implementation wise. My idea was to limit this new feature to UserWidgets. Having more delegates on the default palette widgets could be useful, but I think to a lesser degree because its pretty easy as it is right now to manage them within the user widget that they are a part of. I’m still only speaking of UMG experience, not slate. :slight_smile:

That sounds great!

I do things similarly now by creating “SetupMyWidget” and “CleanupMyWidget” functions that I make sure are called by the parent after adding and removing, but in most of my use cases being able to catch those events internally would have been more convenient.

Usually my order of initializing is this: pass any data model object to the widget as a “Expose on Spawn” parameter or set any dependencies right after creating the widget but before adding it to a parent, then call a custom setup method. I agree that depending on your preferred order of initializating widgets, an add trigger may not be so interesting by itself. I put it in there as a mirror to the removed event, so that where the removed trigger can be used to clean up things (like events bound to external delegates), the added event can be used to prepare the widget to be reused (re-adding the events) since widgets can potentially be removed and readded over and over.

Closing the pull request for now. Maybe its just me plus a few others who wanted an widget added/removed event to hook things up to. If anyone else out there has been wanting that as well, please drop a message. :slight_smile: I hope this or something similar will be added at some point, since working with customized source isn’t an option for me for contracted projects.

Hello. I’ve just come across a situation in which it would be useful to me to have widget added and widget removed events.

I have a widget that needs to begin animating the moment it’s added to the viewport and this seemed to be the obvious method, but it doesn’t exist.

Short of this, can anyone please suggest a sensible way to trigger code (graph) in the widget when it’s added to the viewport?