In this post, we explore how to make draggable widgets in UE. In particular, I’d like to make a generic draggable window-type widget. See the video demo for example widgets that we’ll be working with.
In particular, I will be integrating our inventory and stats widget that we’ve created in previous posts, like this Stats widget.
The content is derived from the documentation available in Unreal Engine, so it may be useful to check that out too if there’s anything unclear.
Creating Drag and Drop UI in Unreal Engine | Unreal Engine 5.0 Documentation
Movable title bar
The key thing that I want to do is create a widget representing the top of the window, which upon drag, will move the entire window.
Note that the Title text is bound to a variable Title
.
The title variable is also instance editable and exposed on spawn as you can see from the screenshot.
Create another variable, ‘ParentWidget’ of ‘User widget’ class and also make it instance editable and exposed on spawn.
Now you can implement the ‘close’ button functionality, by making the parent widget not visible – there’s many ways of achieving this, so feel free to do whichever you prefer.
On Mouse Button Down
Ok now that we have our base widget created, we want to override the functions for ‘On Mouse Button Down’.
If you hover your mouse over the functions tab on the left, you should see the ‘override’ option pop up. Click that and find the ‘On Mouse Button Down’ function.
This is where the docs will differ slightly.
Here we obtain the mouse event which gives us the absolute co-ordinates. The difference is that rather than using this widget geometry, I use the parent widget geometry. Because it is the parent widget that we want to move.
We store this Vector2D as a variable, Drag offset and we can start detecting drag.
Detecting drag
When drag is detected, we want to create a widget which will be used for drag visual.
To some degree, this is optional – and you can customize it as per your requirements. Essentially it will be the widget which you will see moving around as you drag with your mouse – play around with what you want to display!
There’s 3 more things we need to look at which are connected to this:
- Drag widget
- Drag Drop Operation
- Drop function
Drag widget
The Drag widget is what will be used to visually represent our window – so design it as per your requirements!
Here we simply have a Sizebox and Border component with a tint.
You will want to add Widget Reference variable to this widget and make it instance editable and exposed on spawn.
For the event graph, we implement the Event Construct.
The main thing that we do is:
- set the parent widget to hidden (because this one becomes visible)
- update the widget size box dimension with that of the parent widget
So when we create the drag widget, it makes the parent widget invisible and its sized appropriately to the parent widget too.
Drag Drop Operation
This is a type of UE blueprint. When you’re creating a new blueprint, search for ‘drag drop’ and you should find it.
In my case, I named it ‘WidgetDrag’.
On Drag Detected, we create this widget by selecting it on Create Drag Drop Operation, then selecting it under the class.
The only thing we need to add here are two variables, WidgetReference and DragOffset.
Make sure they are both instance editable and exposed on spawn.
Drop functionality
Ok now we’re detecting drag, we’re drawing the drag widget and we’re handling the drag itself using the Widget Drag.
The last part is actually detecting the dropped widget and updating the effects. This is done via our other widget, which has the canvas.
This widget mainly contains the canvas panel and the widgets that we’ll be moving around.
You will need to ensure that the visibility is set to visible and set to be is variable if its not by default.
For the time being, I am not registering custom inputs, so I manually update the visibility of widgets using this:
I will change the above to use enhanced input system, but just showing how it is for now.
Now we want to do the On Drop behavior- click on override in functions and find it there.
This is where we’re utilizing the WidgetDrag – specifically we’re fetching the stored widget reference and drag offset.
The main flow:
- start dragging window
- take note of where mouse is in reference to widget (not screen)
- drop window to new position
- take note of current position
- re-add the widget at the new mouse position, adjusted by initial drag
Link the window to your parent widget
Finally, we need to link your Movable Title Bar Widget to the parent widget.
So for example, here’s me creating the Inventory widget:
Bear in mind, I’ve exposed the title bar so I can override the default title on the right (highlighted).
The title bar also has is variable ticked.
On the event construct I set Parent Widget of the Movable title bar to self.
This means whenever the player moves the title bar, it will be moving this widget.