How-To: Sliders
Goal: put a slider on screen that steps sensibly on a gamepad, shows the player where focus is, and picks up the project's look without being styled by hand.
UCrimsonAnalogSlider is a drop-in replacement for CommonUI's UAnalogSlider (and therefore for USlider), so an existing BindWidget of either type still resolves after you reparent.1. Place the widget
Drag a Crimson Analog Slider into your widget instead of a Slider or an Analog Slider. There is nothing to wire: it is a UAnalogSlider subclass, so Value, MinValue, MaxValue, StepSize, OnValueChanged and every other inherited property and event work exactly as before. Mouse dragging is untouched.
UCrimsonAnalogSlider adds no Blueprint functions and no delegates of its own - everything it does is configured through the properties below and happens automatically. Anything you call on it is inherited from UAnalogSlider / USlider.OnValueChanged, exactly as a stock slider does.2. Tune the held-repeat stepping
The stock slider paces its repeat off stick deflection, so a fully pushed stick runs at top speed from the first frame and overshoots a short range before the player can let go. UCrimsonAnalogSlider instead does what every OS does with a held arrow key: one step immediately, a pause, then a steady repeat whose step grows.
| Property | Default | What it does |
|---|---|---|
bUseHeldRepeat | true | Off restores stock UAnalogSlider behavior entirely. |
RepeatInterval | 0.15 s | Seconds between repeats once the hold is established. The cadence stays constant. |
AccelerationDelay | 0.35 s | How long the hold runs at one step before the ramp starts. |
AccelerationRampTime | 1.5 s | How long the ramp takes to reach full speed after the delay. |
MaxStepMultiplier | 3.0 | The step is multiplied by up to this at the top of the ramp. |
The size of one step is the inherited StepSize; these five decide how often and how hard it repeats. A tap is exactly one step, and releasing or losing focus resets the ramp, so a short correction never inherits the speed of the last long drag.
Gamepad_LeftX (horizontal sliders) and Gamepad_LeftY (vertical), past a 0.5 deflection threshold - the same stick CommonUI navigates with, which is what makes a focused slider absorb the axis instead of moving focus off it. D-pad and arrow keys arrive through navigation rather than key-down, because SSlider routes its stepping that way.3. Keep the focused state visible
FSliderStyle has Normal, Hovered and Disabled brushes and no focused brush at all. A focused slider is therefore drawn pixel for pixel like an unfocused one - and on a gamepad, where every neighboring button lights up on focus, that reads as "focus is on nothing" even while focus is sitting correctly on the slider.The workaround is a handle tint rather than a brush swap, because there is no brush slot to swap:
| Property | Default | What it does |
|---|---|---|
bTintHandleOnFocus | true | Tints the handle while the slider holds focus. |
FocusedHandleColor | The house accent | The tint. FLinearColor, so set it to your own accent. |
The resting color is not hard-coded: the widget captures the slider's own SliderHandleColor when it pushes its settings to Slate, and restores exactly that when focus leaves. An author who set a custom resting color keeps it.
4. Apply the shipped theme
bUseProjectSliderStyle (default on, and a property of the slider, not of the settings object) writes six materials from UCrimsonUISettings into the widget's WidgetStyle, so a dropped slider is themed with zero per-widget setup and every slider in the project changes together.
Content/, but the references are config values with no C++ defaults - a C++ CDO cannot name a content asset without hard-coding a path, and hard-coding one would tie the plugin's code to its own content layout. Until you point them somewhere, a themed slider draws the engine's stock gray.Project Settings -> Crimson -> Crimson UI -> Slider. Set the six material fields to the shipped instances in /CrimsonUI/UI/Foundation/Materials/Slider/ (tick Show Plugin Content in the Content Browser first, or they will not appear in the picker):SliderBarMaterial = MI_CrimsonSlider_Bar, SliderBarHoveredMaterial = MI_CrimsonSlider_Bar_Hovered, SliderBarDisabledMaterial = MI_CrimsonSlider_Bar_Disabled, SliderThumbMaterial = MI_CrimsonSlider_Thumb, SliderThumbHoveredMaterial = MI_CrimsonSlider_Thumb_Hovered, SliderThumbDisabledMaterial = MI_CrimsonSlider_Thumb_Disabled.
Two more fields in the same category size the widget and already have real defaults: Slider Thumb Size (8, 16) and Slider Bar Thickness 4.0.
M_UI_ChamferBox, which also lives in CrimsonUI - so pointing at them adds no cross-plugin content reference. Swap in your own UMaterialInterface assets here to re-theme every slider in the project at once.bUseProjectSliderStyle false on an individual slider whose visuals the surrounding widget paints itself - a settings scalar row, for instance, that hides its own bar and draws a track, fill and default tick underneath. The stepping and focus behavior are unaffected.See also
- How-To: Buttons & Action Glyphs - the other common control, and the same focus rules.
- How-To: Build an MVVM Screen - binding a slider's value to a view model instead of an event graph, which is where most settings-style sliders end up.
- API Reference -> Buttons, tabs, lists, drag-drop - the full property list.