A issue about UCanvasPanelSlot::SetPosition

I create a UMG element add it in viewport in my application, and I change the position of UMG element dynamically:


UCanvasPanelSlot* Canvas = Cast<UCanvasPanelSlot>(MyButton->Slot);
Canvas->SetPosition(FVector2D(X, Y));

while my application was running in a maximized mode in UE4Editor, the position is correct, but when running in a windowed mode in UE4Editor, the position of UMG element is incorrect.
Is a bug of UMG API? or I used the wrong API? how about the other way to change the position of UMG element?

Depends where your Pivot Point of the Slot is. Also, you of course have to take the screen-resoulution in mind. X 200 might be the right position on FUll-Screen Mode, on Windowsed mode X 200 might be way to far on the right. I always recommend calculating percentages, so everything stays the same on all resoultions.

Ty for your suggestion! Additionally, how to set Pivot Point of the Slot?

tbh, I don’t know for C++, I have to admit that I do all my UI Stuff in Blueprints (even though I am a total C++ Fanboy hehe)

All right, BP also is well, could you show me the BP node to set Pivot Point of the Slot?

You need to factor in things like DPI and the viewport size when you change resolution, the same is true when you’re doing it in Blueprint. Here’s an excerpt from some of my source code, which places a SizeBox around an object in-game and factors in screen res etc.



// Call this once per-frame, on tick. To avoid re-calculation, or call it when settings / screen res changes.
	FORCEINLINE void ComputePlacementParams()
	{
		// Cache some of the shared parameters
		GetWorld()->GetGameViewport()->GetViewportSize(ViewportSize);
		ViewportCenter = ViewportSize / 2.f;

		// Root Panel Data
		CanvasSize = RootPanel_Ptr->GetDesiredSize();
		Divisor = CanvasSize / ViewportSize;
		DPIScaling = GetDefault<UUserInterfaceSettings>()->GetDPIScaleBasedOnSize(FIntPoint(ViewportSize.X, ViewportSize.Y));
        }




// Called on tick to set location. 'IssScreenLocation' is the central position on-screen of where I want the widget.
		const FVector2D AnchorDivided = ((IssScreenLocation - ((ISSTrackerSlot_Ptr->GetSize() * DPIScaling) / 2.f)) * Divisor) / CanvasSize;
		const FAnchors NewAnchors = FAnchors(AnchorDivided.X, AnchorDivided.Y, AnchorDivided.X, AnchorDivided.Y);

		ISSTrackerSlot_Ptr->SetAnchors(NewAnchors);
		ISSTrackerSlot_Ptr->SetPosition(FVector2D::ZeroVector);


In this case, ISSTrackerSlot_Ptr is a UCanvasPanelSlot.

Awesome! Ty again! these code are very useful for me. Have a nice day!