Two UserWidgets with NativePaint override: only one shows

image

This is the widget hierarchy within my UMG asset. In principle it works all fine. There are two custom widgets there. Both are BluePrints that inherit a C+±class that again inherits from UUserWidget.

I override the NativePaint function in both of them. However, my code UUserWidgetHUDBorder::NativePaint doesn’t result in anything being drawn on the screen. The code in UMyHUDWidget::NativePaint works fine.

I put a UE_LOG in UUserWidgetHUDBorder::NativePaint, too, to check whether the code gets executed at all – and sure it does. Only the drawing is missing.


The reason why I use two UserWidgets is this: the first one is outside the RetainerBox. The second one is inside it, because I am applying a distortion on most of my HUD. Some parts of my HUD are drawn distorted, others should be drawn without distortion. Those latter ones, outside the RetainerBox, don’t show.

I also put a TextBlock in my UserWidget. The TextBox does show, only the custom drawing code in NativePaint doesn’t work.

1 Like

Correct use of LayerId solved my problem:

int32 UMyHUDWidget::NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry,
                                const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId,
                                const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	const auto PG = AllottedGeometry.ToPaintGeometry();
	const auto ViewportScale = UWidgetLayoutLibrary::GetViewportScale(GetWorld());
	const auto Vec2DSize = UWidgetLayoutLibrary::GetViewportSize(GetWorld());
	const auto Width = Vec2DSize.X / ViewportScale;
	const auto Height = Vec2DSize.Y / ViewportScale;
	const auto X0 = .2;
	const auto Y0 = .2;
	const auto P0 = FVector2D(Width * X0, Height * Y0);
	const auto P1 = FVector2D(Width * X0, Height * (1. - Y0));
	const auto P2 = FVector2D(Width * (1. - X0), Height * (1. - Y0));
	const auto P3 = FVector2D(Width * (1. - X0), Height * Y0);

        // chose a new layer
	const auto LayerIdNew = LayerId + 1;
	
	const TArray<FVector2D> Points = { P0, P1, P2, P3, P0 };

        // pass on the latest layer id
	FSlateDrawElement::MakeLines(OutDrawElements, LayerIdNew, PG, Points);
	return Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerIdNew, InWidgetStyle,
	                          bParentEnabled);
}
3 Likes