How to detect true widget visibility

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)

	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! :slight_smile: