I can’t seem to find any way to detect whether a given widget is visible. IsVisible() just checks the widget’s own visibility status, but doesn’t take into account its hierarchy, which may include a parent that is hidden.
There are 2 ways you could go about it:
the clunky way: (although you could write a macro)
- GetParent of the widget
- check if it’s valid
- check if it’s the one you’re looking for
- if yes → check visiblity
- if no → rinse & repeat
use Rama’s plugin:
Fetch the desired parent and check its visibility. This is still not ideal but should work better. The downside is that you need the plugin.
I wrote something like this as a function, but I wish there’d be such functionality cached from the engine already, since it’s needed and used somewhere in the underlying slate anyway I believe (for layout/visibility invalidation etc.). I didn’t dive deeper into it yet, though. So, for now this works for me:
bool resultVisibility = true;
UWidget* hierarchyWidget = this;
while (hierarchyWidget)
{
// WARNING: don't use outerWidget->IsVisible() since that uses inner slate widget which might not yet be initialized here!
// GetVisibility uses the UMG defined visibility which is exactly what we want and need here.
bool isCurrentVisible = hierarchyWidget->GetVisibility() == ESlateVisibility::Visible ||
hierarchyWidget->GetVisibility() == ESlateVisibility::HitTestInvisible ||
hierarchyWidget->GetVisibility() == ESlateVisibility::SelfHitTestInvisible;
resultVisibility = resultVisibility && isCurrentVisible;
if (!resultVisibility)
{
break;
}
UWidget* nextHierarchyWidget = hierarchyWidget->GetParent();
// if outerWidget is nullptr it means we reached the root container of the current UserWidget...
if (!nextHierarchyWidget)
{
//...Get the WidgetTree...
if (UWidgetTree* currentWidgetTree = Cast<UWidgetTree>(hierarchyWidget->GetOuter()))
{
//...and the corresponding parent UserWidget...
if (UUserWidget* currentUserWidget = Cast<UUserWidget>(currentWidgetTree->GetOuter()))
{
//...and take it as UWidget to consider in next loop
nextHierarchyWidget = currentUserWidget;
}
}
}
hierarchyWidget = nextHierarchyWidget;
}
Thanks, this works pretty good!