I have a basic Slate button class derived from the SStrategyButtonWidget class in the StrategyGame sample.
I need to position this button directly under the mouse cursor at one point in the game. What’s the best way to do that? Clearly there’s no SetPosition() I can call – should I be using a callback set from my main UI widget’s Construct(), or setting it directly somehow?
Hey i end up using this same solution, problem is the widget follow with some sort of lag. It’s not slow but it looks like its getting updated with a delay.
Do you have this same problem and did you find a way to make it better ?
Slate widgets are aligned/positioned automatically using container widgets like VerticalBox or HorizontalBox. If you want to control exact position of a widget you can for example create a new window and put your widget inside this window. SWindow has MoveWindowTo() method that is what you are looking for.
So here is a very raw code that should help you moving your widget:
// create actual window with helper function (you can actually use `SNew(SWindow)` if you want but its just easier to use CursorDecorator)
TSharedPtr<SWindow.> MyWidgetWindow = SWindow::MakeCursorDecorator();
// Add widget you want to display to the window
// Add window to Slate but dont show it yet!
Now you can move/show/hide MyWidgetWindow with functions like MoveWindowTo, ShowWindow, HideWindow
When i try to use window i end up with a bunch of errors. Window appears but they are not draggable, or take the fullviewport, or crash when you click the close button…, with the example you provide i just succeed to make it appear in the middle and i can’t close them or move them. I have to close the editor to make them disappear.
I would prefer to use SWindow rather than Soverlay or Scanvas but i can’t make them work.
Is it working for you with just that code ?
CursorDecorator is not a regular window, you can actually think of it as a container to other windgets. You wont be able to resize or move it with your mouse inside game- you can only do this via code. I didnt mention that but you also have to clean up after youre done using this window or else SlateApplication will crash. To remove window from memory you just call RequestWindowDestroy on a window in your end game code or in Widget’s destructor. I prepared a sample code presenting usage of this method. This is just a simple widget - SMyOverlay, that extends SOverlay widget and controls behaviour of mentioned window. All you have to do is call GEngine->GameViewport->AddViewportWidgetContent(SAssignNew(OverlayWidget, SMyOverlay)); somewhere in you game begin code and then call OverlayWidget->SetWindowContainerVisibility(true/false) to show or hide window whenever you want.
Code should be easy to understand but if you have any problems let me know.
class SMyOverlay : public SOverlay
// REMEMBER TO CLEAN UP ! ! !
void Construct(const FArguments& InArgs)
WindowContainer = SWindow::MakeCursorDecorator();
// Im using Stooltip only because it looks nicer than empty window
// Add whetever you want here
.Text(FText::FromString("Window Container Text"))
const int32 NumSlots = InArgs.Slots.Num();
for (int32 SlotIndex = 0; SlotIndex < NumSlots; ++SlotIndex)
// uncomment to show window after construction
virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) OVERRIDE
// Update WindowContainers location, you can add offsets to mouse position here
WindowContainer->MoveWindowTo(MouseEvent.GetScreenSpacePosition() + FSlateApplication::Get().GetCursorSize());
return SOverlay::OnMouseMove(MyGeometry, MouseEvent);
void SetWindowContainerVisibility(bool NewVis)
// change WindowContainer's visibility
NewVis ? WindowContainer->ShowWindow() : WindowContainer->HideWindow();