How to destroy UMG widget?

You could exec_flow -> ‘Get All actors of class’ specify your widget blueprint as target -> Get array elem -> Destroy Actor.

1 Like

Widgets are not actors, so finding them as actors won’t work. Neither are they components. They have their own set of management functions.

I did eventually solve this. I think I needed to cast the UWidget type to something else.

1 Like

This is an interesting topic. Widgets don’t refresh or redraw themselves every frame, they have an invalidation routine and can be set to volatile and things like that. There shouldn’t be much of a performance hit once a widget has been drawn and isn’t doing anything.

In the same way if you collapse a widget, that’s it, it should stop having an effect on performance entirely, because invisible, insubstantial widgets never have a reason to be invalidated again.

Destroying and creating something over and over and putting more work on garbage collection is always a bad idea, definitely try to get some re-use in there.

1 Like

I was also interested in this problem.
Because “detach” and “delete” have different meanings.

In C/C++ language, memory is always allocated and released manually.
As a programmer, it’s embarrassing to leave memory and languish resources.
For those familiar with C/C++, this is a natural question.

I will say there is definitely a use case for destroying widgets, for example, if a Widget is designed to be created with specific info at construct time and that info will never be re-used (and storing the reference and re-running the initialization is inconvenient) or if I know that a Widget will never be seen again then there is a case from a design perspective where I would want to destroy a Widget.

This code in C++ works for me, have tested and it seems like the Widget will be removed from memory entirely:

.h


UFUNCTION(BlueprintCallable, Category = "Optimization", meta=(DefaultToSelf=Object))
static void DestroyObject(UObject* Object);

.cpp



void UYourFunctionLibrary::DestroyObject(UObject* Object) {
    if (Object)
    {
        Object->ConditionalBeginDestroy();
    }
}

6 Likes

Construct is called on a widget every time it is added to the Viewport though even if it hasn’t been garbage collected so why would you want to specifically destroy it?

I have several Widgets that are part of a bigger widget and the data is dynamic, and the number of Widgets is also dynamic. I don’t want to have to store an array of Widget references and then iterate through each one to reconstruct the UI, and add a new widget to the list of references if there are not currently enough Widgets. For me, it’s not about the performance overhead, the difference in construct time would be so minuscule.

Keeping unused Widgets in memory also has a side effect on certain operations, such as retrieving all Widgets of a class, and if I know that I can optimize that call by culling Widgets that I know won’t be used, I should be able to do that.

I want to be able to manage the memory in a way that I want that fits in with my design pipeline, and I don’t see why I shouldn’t be allowed to explicitly destroy an Object if I feel like that’s best for my applications.

Trying this out, will edit if this solves my current leak. Seems like a better way then removing from parent just praying garbage collection finds it (it hasnt for me)

This works great.

In my case deleting the widget from memory was necessary, because I store different types of widgets in the same variable dynamically. Not deleting it from the memory (specifically calling the CreateWidget<T>() function) caused the engine to crash.

What about a case where widget blueprint starts async function and then you remove it form parent before it finishes, Say you click News from Main Menu, you remove Man Menu, you show News widget and start fetching news and populate listview, then you click back so you remove News widget and Create Main Menu again - what then? News widget is not destroyed just removed from parent and function keep executing.

I too ran into this issue and I expected the widgets to have been garbage collected. A lot of times I spawn an instance of a UMG widget I know I will later destroy and not have a reference to at all, so it being in memory is not useful.

Also I wrote my game to dynamically recreate the HUD completely when a new pawn is possessed or when my game enters/exists VR. I noticed I actually have old instances of my widgets still running code that they shouldn’t be since they’re supposed to be deleted, and I get all sorts of weird errors with references being set to none. It was a huge mystery to me until I debugged with Blueprint Debugger and saw I had way more instances than I was supposed to of UMG widgets.

I had some success with ConditionalBeginDestroy but it seems like I need to somehow call this for every child UMG widget too?

Actually I solved this by calling Collect Garbage after.

2 Likes

So I just into this issue. I’m working only in Blueprints (no access to code). Does anyone have a solution that could be done in blueprints?

Not working on UE4.27.2 .

This code is just to call the “Event Destruct” function in blueprints in the Widget’s graph, it doesn’t actually kill the instance, in fact it doesn’t even execute a function in relation to the object.

That code is called when the widget is destructed, not something that should be called.

It seems like the correct way is to make sure there are no strong references in memory to the widget so it gets garbage collected, and to manually invoke the garbage collector so it happens ASAP.

1 Like