Quick and Dirty Custom Scrollbar for the built-in Scrollbox UMG Widget
A rundown of how we setup a custom Scrollbar in UMG
NOTE: All Images shown here are WORK-IN-PROGRESS and do not represent the final product
Looking at the Slate Scrollbox, we see it simply setting a bool for later use during Tick:
Looking at that, the Scrollbox looks up its Panel Geometry followed by that Panel’s desired size. GetScrollComponentFromVector() simply checks what Orientation the Scrollbox is set to and returns either the X or Y component. The bit that calculates the actual end scroll offset, simply subtracts the Scroll Panels Geometry size from its desired size. Simple! Nevertheless, there is no “GetEndScrollOffset” node! How do we reproduce this in BP?
This cluster of nodes that execute on Initialize calculate the Scrollboxes Height and store it for later use during the SliderValuerChanged event (shown above) and in the GetSliderValue function (shown below).
The Initialize nodes replicate the code in SScrollBox::Tick() function, but with a few tweaks like taking each elements padding into account. Once we have the Scrollbox Height, we can use it to drive the Slider and have it and the Scrollbox interact through this helper Object. Note: I am assuming that everything is in the vertical orientation here hence using only the Y components of Size.
We create the helper object that holds all of the calculation logic and call its Initialize event after a small delay. The delay is to make sure all of the widgets are constructed prior to grabbing their size in the Initialize call.
The latter will tell the Slider to move to a position based on the Scrollboxes offset when scrolling using a mouse wheel, like so:
I actually began setting this whole thing up as a UserWidget to make it a bit more convenient and portable. However, it turns out the UserWidgets cannot have children added to them via the Editor. So dragging in Widgets does not work. At least not yet. Something I would love to see added to UMG soon; it would add a great amount of flexibility and convenience to creating custom behavior!
Happy to answer any questions and if you know of an even better way to achieve something like this, do let me know.