Draw a line from a widget position to 3d space on screen

Been trying to do this for a while and i think its because dont understand 3d math.

What ive got now is doing something in terms of 3d position but it a quite a bit off.

What ive tried so far -

int32 UCodeEditor::NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	if (!OwningInteractable)
	{
		UE_LOG(LogTemp, Warning, TEXT("Code Editor has no owning interactable"));
		return LayerId;
	}

	FVector2D InteractableLocation;
	UGameplayStatics::ProjectWorldToScreen(
		GetWorld()->GetFirstPlayerController(),
		OwningInteractable->GetActorLocation(),
		InteractableLocation
	);

	FVector2D ScreenEnd = TextInput->GetCachedGeometry().AbsoluteToLocal(InteractableLocation);

	FPaintContext Context(AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
	FVector2D ScreenStart = TextInput->GetCachedGeometry().GetLocalPositionAtCoordinates(FVector2D(1.f, 0.f));
	UWidgetBlueprintLibrary::DrawLine(Context, ScreenStart, InteractableLocation, FLinearColor::Yellow, true, 2.0f);

	return LayerId;
}

It would be very helpful if you could add a screenshot of what you’re seeing vs. what you want to see. Your code looks largely okay. The issues that you have might actually be related to 2D rather than 3D math and widget absolute/local position translation.

Hi, This was a while back and since figured it out. I Ended up with-

int32 UCodeEditor::NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	if (!OwningActor)
	{
		UE_LOG(LogTemp, Warning, TEXT("Code Editor has no owning interactable"));
		return LayerId;
	}

	// draw line from widget to actor
	FVector2D InteractableLocation;

	UWidgetLayoutLibrary::ProjectWorldLocationToWidgetPosition(
		GetWorld()->GetFirstPlayerController(),
		OwningActor->GetActorLocation(),
		InteractableLocation,
		false
	);

	// get widget geometry
	FVector2D ScreenEnd = TextInput->GetCachedGeometry().AbsoluteToLocal(InteractableLocation);

	FPaintContext Context(AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
	// get top right corner of widget
	FVector2D ScreenStart = TextInput->GetCachedGeometry().GetLocalPositionAtCoordinates(FVector2D(1.f, 0.f));
	UWidgetBlueprintLibrary::DrawLine(Context, ScreenStart, InteractableLocation, FLinearColor::White, true, 2.0f);

return LayerId;
}
1 Like