How to draw lines under certain widgets/UI elements?


The drawn lines should be under the nodes(those robots images) and under the UI from outercanvas(outercanvas and innercanvas are used for panning and zooming)

You can also experiment with passing in a custom LayerId in the NativePaintstrong text for the MakeLines and super call

.h

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "UpgradeWidgetTree.generated.h"

class UCanvasPanel;
/**
 * 
 */
UCLASS()
class YOUR_API UUpgradeWidgetTree : public UUserWidget
{
	GENERATED_BODY()
public:	

	virtual int32 NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
	
	UPROPERTY(meta = (BindWidget))
	UCanvasPanel* InnerCanvas;

	UPROPERTY(meta = (BindWidget))
	UWidget* Slot1;

	UPROPERTY(meta = (BindWidget))
	UWidget* Slot2;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 LineLayerId;
	

};

.cpp


#include "UpgradeWidgetTree.h"
#include "Components/CanvasPanelSlot.h"
#include "Blueprint/WidgetLayoutLibrary.h"
#include "Components/CanvasPanel.h"
#include "Rendering/DrawElementTypes.h"

int32 UUpgradeWidgetTree::NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{	
	int32 LayerID = Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
	
	if (InnerCanvas != nullptr && Slot1 != nullptr && Slot2 != nullptr)
	{		
			UCanvasPanelSlot* CanvasSlot0 = UWidgetLayoutLibrary::SlotAsCanvasSlot(Slot1);
			UCanvasPanelSlot* CanvasSlot1 = UWidgetLayoutLibrary::SlotAsCanvasSlot(Slot2);

			FVector2D AntchorPosition = InnerCanvas->GetCachedGeometry().GetLocalSize() * CanvasSlot0->GetAnchors().Minimum;
			FVector2D Position0 = AntchorPosition + CanvasSlot0->GetPosition();
			FVector2D Position1 = AntchorPosition + CanvasSlot1->GetPosition();
												
			FSlateDrawElement::MakeLines(
				OutDrawElements,				
				LineLayerId,				
				InnerCanvas->GetPaintSpaceGeometry().ToPaintGeometry(),
				{ Position0,Position1 },
				ESlateDrawEffect::None,
				FLinearColor::Blue,
				true,
				5.0f
			);					
	}	
	return LayerID;	
}

Alignment for both boxes is set to 0.5 , 0.5
Line layer ID = 50

2 Likes

also i dont really understand what he wanted, use widget need to be highest number, like 99999,(means on top) or you go thought the current drawer , opengl and so on and u base on that. using game engine if your developing is easy, but using this to interloop functions u need to hook

Solution was to make a single widget that entirely handles all the lines and then you can just batch draw as many as you want, and make them draw beneath/on top of other things by Z-order or parenting.

About your second solution i already tried that before, and it won’t work, it worked on editor with id as “50” but in cooked build its completely unreliable, it even draws on one of the nodes and then beneath other node.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.