[UMG / UserWidget / Engine 4.19 -> 4.20] The Destroy process of UserWidget seems strange.

When UserWidget is garbage collected, In ConditionalBeginDestroy On UObject, ObjectFlags change RF_BeginDestroyed
In next Step, BeginDestroy On UserWidget, RemoveFromParent function starts

Through Engine Version 4.19 → 4.20, RemoveFromParent Check !HasAnyFlags(RF_BeginDestroyed)
So, Isn’t RemoveFromParent call meaningless on BeginDestroy? And
If World and LocalPlayer are destroyed on EndPlayMap, what should we do if SWidget’s resources are not released?

Thank you in advance!!

void UUserWidget::BeginDestroy()
{
Super::BeginDestroy();

//TODO: Investigate why this would ever be called directly, RemoveFromParent isn’t safe to call during GC,
// as the widget structure may be in a partially destroyed state.

// If anyone ever calls BeginDestroy explicitly on a widget we need to immediately remove it from
// the the parent as it may be owned currently by a slate widget. As long as it’s the viewport we’re
// fine.
RemoveFromParent();

// If it’s not owned by the viewport we need to take more extensive measures. If the GC widget still
// exists after this point we should just reset the widget, which will forcefully cause the SObjectWidget
// to lose access to this UObject.
TSharedPtr SafeGCWidget = MyGCWidget.Pin();

if ( SafeGCWidget.IsValid() )
{
SafeGCWidget->ResetWidget();
}

}


void UUserWidget::RemoveFromParent()
{

if (!HasAnyFlags(RF_BeginDestroyed))
{

if (FullScreenWidget.IsValid())
{
TSharedPtr WidgetHost = FullScreenWidget.Pin();

// If this is a game world add the widget to the current worlds viewport.
UWorld* World = GetWorld();
if (World && World->IsGameWorld())
{

if (UGameViewportClient* ViewportClient = World->GetGameViewport())
{
TSharedRef WidgetHostRef = WidgetHost.ToSharedRef();

ViewportClient->RemoveViewportWidgetContent(WidgetHostRef);

if (ULocalPlayer* LocalPlayer = GetOwningLocalPlayer())
{
ViewportClient->RemoveViewportWidgetForPlayer(LocalPlayer, WidgetHostRef);
}

FWorldDelegates::LevelRemovedFromWorld.RemoveAll(this);
}

}
}
else
{
Super::RemoveFromParent();
}
}
}

Hello,

We’ve recently made a switch to a new bug reporting method using a more structured form. Please visit the link below for more details and report the issue using the new Bug Submission Form. Feel free to continue to use this thread for community discussion around the issue.

https://epicsupport.force.com/unrealengine/s/

Thanks