set position in viewport widget not working

Hi devs i have a issue where i am trying to use (set position in viewport) node but is not working i have test on unreal engine 5.0 and the same pice of code works fine here is the example

4 Likes

If the element / control / widget is within a container, you might have issues moving it; because the container forbids it from moving.

Thanks for the response, the widget i am trying to change the position is a border with a horizontal box with items inside, so to controll the position of widget is should wrap with a canvas ? so i can use set position in the viewport ? thanks.

Yes something like that! Let me know if you ended up solving the issue! :slight_smile:

Thanks for the help i have found the solution.


Still don’t explain why that set view port node is not working properly but doing so research i have found a much better way to do this that follow the screen size.

One more thing for those who are tring to do the same i am leaving the widget that i creating as a reference because the offset is very important to get right to, the offset is mark by the red circle

1 Like

Hi! I can confirm. We have just ported our project from 5.0 to 5.1. We narrowed down when our movable widgets stopped working. It is after porting to 5.1.
I looked into Set Position in Viewport function in C++, and indeed - it has changed a lot from 5.0 to 5.1.
Basically, this function is unusable now. Completely broken.
I have a widget NOT in container. Just created and Add To Viewport called on it. This method works perfectly on UE 5.0 and before. 5.1 clearly broke it.

5 Likes

Yes the same here, unfortunately i way i could fix that issue is to create a widget with an empty canvas add my widget target as a children them based in the slot change the position.

1 Like

Yeah I did very similar thing, now my movable stuff is on empty canvas and I am moving the slot, which works just as good for my use case. However the issue is still there, and the function should be fixed. I’ve created a bug report for this one.

4 Likes

+1 Also broke our placed/draggable widgets in our game after moving from 5.0 to 5.1

Our c++ code however is not broken:

            CanvasSlot->SetPosition(TargetLocation);

Salut, en attendant moi j’utilise “Set render Translation” pour le repositioner correctement
2e26c6fce044c0659cc59638653417f4

9 Likes

This works for me in 5.1, in this case from world position to screen space, but it might help someone out.

4 Likes

Thanks ^^ you really helped a somebody

1 Like

tout le monde le fait en anglais, personne va piger

Sadly still broken in 5.3.2. Really disappointing since I am trying to align things based on the size (i.e. pixel count) of the viewport, so this node is the bottleneck for me since I want to set positions based on pixels, not relative to canvas slots or positions in designer.

1 Like

Just to add this still does not work properly in 5.4.1. I wrote a workaround in C++ in order to render a popup on my HUD at the mouse cursor location during an OnHovered event fired from a UMG button. Relevant example of the code I’m using in case anyone else is searching for this (slightly more detailed example on my github):

// Returns a position you can feed to a CanvasPanelSlot that works at any resolution
FVector2D GetDPIScaledMousePositionForUMG(APlayerController* controller)
{
	FIntPoint viewportDims(0, 0);
	FVector2D mousePos(0.0f, 0.0f);
	controller->GetViewportSize(viewportDims.X, viewportDims.Y);
	controller->GetMousePosition(mousePos.X, mousePos.Y);

	const UUserInterfaceSettings* uiSettings = GetDefault<UUserInterfaceSettings>(UUserInterfaceSettings::StaticClass());
	if (uiSettings)
	{
		float currentDPIScale = uiSettings->GetDPIScaleBasedOnSize(viewportDims);

		// This is assuming your UI is authored at a 1.0 DPI scale
		float dpiMouseScale = 1.0f / currentDPIScale;

		return mousePos * dpiMouseScale;
	}

	return mousePos;
}

void UMyHUDCClass::Setup()
{
	// NOTE: myPopup is NOT a UPROPERTY, which means it is fair game for Garbage Collection at any time.
	// AddToRoot explicitly prevents the GC from destroying this runtime created object until RemoveFromRoot is called.
	myPopup = CreateWidget<UMyUserWidgetClass>(this, s_popupWidgetClass);
	myPopup->AddToRoot();
	myPopup->SetVisibility(ESlateVisibility::Hidden);

	// This assumes a root-level CanvasPanel named HUDCanvas on your HUD
	if (HUDCanvas)
	{
		UPanelSlot* panelSlot = HUDCanvas->AddChild(myPopup);
		popupPanelSlot = Cast<UCanvasPanelSlot>(panelSlot);
	}
}

void UMyHUDCClass::ShowPopupAtCursor()
{
	myPopup->SetVisibility(ESlateVisibility::Visible);

	APlayerController* controller = GetOwningPlayer();
	FVector2d scaledMouse = GetDPIScaledMousePositionForUMG(controller);

	if (popupPanelSlot)
	{
		popupPanelSlot->SetPosition(scaledMouse);
	}
}

5.4.4 still broken

I’m having a very bizarre issue.

I can confirm that from at least 5.3 to 5.4.4 this node does work, but only if it’s for widgets that aren’t children of other widgets.

If I create a widget at runtime and have it follow my cursor using this node then it works fine.

If the widget is part of another widget, it does not. Even if that widget is an empty canvas panel, as others have suggested.

The canvas slot workaround works as well.