How to position a widget in the viewport and keep it responsive without a canvas panel?

helo, i’m trying to create a context menu and an item inspector for my inventory, both should appear next to the slot and in both i’m not using a canvas panel. The way that i’m doing is: i’m getting the slot position and passing it to the HUD, which then passes it to these widgets to set their positions. However, it’s not working, and it’s not responsive: if I reduce the screen size, the widget moves extremely far away.

in full screen:

in widow mode:

here how i get my slot position in the slot widget:

FVector2D UInv_ItemSlot::GetSlotPosition() const
{
FGeometry Geometry = GetCachedGeometry();
FVector2D WidgetCenter = Geometry.GetLocalPositionAtCoordinates(FVector2D(0.5f, 0.5f));
FVector2D PixelPosition;
FVector2D ViewportPosition;
USlateBlueprintLibrary::LocalToViewport(GetWorld(), Geometry, WidgetCenter, PixelPosition, ViewportPosition);
UWidgetLayoutLibrary::GetViewportScale(this);
return PixelPosition;
}

and i get the slot position in my inspector and context menu and do this:

SetPositionInViewport(SlotPosition, false);

i already tested using false to bRemoveDPIScale, but nothing has changed

here my widget setup in editor:

i’m using a scale box to override the size, and it’s set to desire on screen with a value of 0.5 in pivot

Hello @riukuh ,
You could try adding the canvas panel and adjusting the anchors properly.

Canvas Panel

Anchor-Points

Let me know if it works!

1 Like

i’m trying to do it without canvas panel, there’s a way to do it without a canvas?

i don’t think so. as it’s the canvas that provides some of those features.

you could implement your own logic for updating the layout, i think there’s a virtual function for that. but it sounds extremely convoluted. i don’t understand your restriction of not using a canvas.

1 Like

I wasn’t using a canvas to avoid each different widget with a single function using one, wasting resources, but now I’ve added them all to the hud with bind widget, the only point now is: I had managed to do it using setpoisitioninviewport, but then it wasn’t responsive and so I put everything on the canvas, but now this position doesn’t work, what do I do?

i did this to set position in canvas:

if (UCanvasPanelSlot* ContextMenuSlot = Cast(ContextMenuWidget->Slot))
{
ContextMenuSlot->SetPosition(SlotPosition);
}

it change the position of the widget, but it’s too far from the desired position, i think it’s because i’m getting the absolute position of the slot and set this position to be where my menu will go, and it’s not converted to relative position to the canvas

You need convert desired absolute position to local canvas slot position.

FVector2D local_position = this->GetCachedGeometry().AbsoluteToLocal(new_absolute_location);
canvas_slot->SetPosition(local_position);

i did this to get position of the slot:

FVector2D UInv_ItemSlot::GetSlotPosition() const { FGeometry Geometry = GetCachedGeometry(); FVector2D LocalLocation; FVector2D WidgetPosition = Geometry.AbsoluteToLocal(LocalLocation); UE_LOG(LogTemp, Warning, TEXT("Slot Position: X=%f, Y=%f"), WidgetPosition.X, WidgetPosition.Y); return WidgetPosition; }

and this in my hud to set position

if (UCanvasPanelSlot* ContextMenuSlot = Cast<UCanvasPanelSlot>(ContextMenuWidget->Slot)) { ContextMenuSlot->SetPosition(SlotPosition); }

but still didn’t work, here’s my hud:

i wanna set position of the context menu and item inspector, but the position i’m getting is wrong, my context menu don’t even appears anymore in my screen

the value that i’m getting in the ue log is different from the position that i simulated that is the right to position my widget in the canvas, and idk what to do

try set anchors to top left for context menu widget.

I recommend watching these two videos about flexible UI system: