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! 