Hi everyone! Today I’m going to be releasing my first open-source module, a custom slider module! There’s not much to say, so I’ll just let you read.
Overview
Basically, this plugin allows you to create sliders that consist of a starting, ending, and increment value. There’s many customization options aswell, the current ones will be listed below.
Note
First and foremost, you will need the Slider module (located here)
Once you have that, you may continue.
API
The API for this module is shown below, if you want to skip that and go straight to the example, go ahead!
Methods
Slider.new()
function Slider.new(holder: GuiBase2d, config: configDictionary)
Description: Creates and returns a slider object.
Parameters:
Parameter | Type | Value |
---|---|---|
Holder | GuiBase2d | Any object, however it must contain an “AbsoluteSize” and “AbsolutePosition” property. The holder must contain a GuiButton named "Slider" |
Config | ConfigDictionary | A dictionary that contains data about the slider, shown below. |
ConfigDictionary:
Key | Type | Value | Optional |
---|---|---|---|
SliderData | SliderDataDictionary | A dictionary which defines the slider’s start, end and increment points. | No |
MoveType | String | A string which defines if the slider should tween to the current position or instantly move (can only be “Tween” or “Instant”) | Yes |
MoveInfo | TweenInfo (or nil if MoveType is “Instant”) | A TweenInfo Object which defines how the slider tweens to the current position. | No |
Axis | String | A string that defines which axis the player must move their mouse on for the slider to move (Can only be X or Y) | Yes |
Padding | Number | A number that defines how many pixels the slider button pads from the start and end of the slider frame. The default value for this is 5 pixels | Yes |
AllowBackgroundClick | Boolean | A boolean which defines whether the slider will have a background click (meaning clicking on the frame will move the slider to that position) | Yes |
SliderDataDictionary:
Key | Type | Value | Optional |
---|---|---|---|
Start | Number | A value that defines the start value for the slider | No |
End | Number | A value that defines the end value for the slider (This must be larger than the start value) | No |
Increment | Number | A value that defines the increments that the slider increases/decreases in | No |
DefaultValue | Number | A value that defines the default value for the slider, if this is set then the slider will start at this value. | Yes |
Notes:
- Will error if it cannot find the Slider button (must be called “Slider”)
- Will error if
SliderData.End
is greater than or equal toSliderData.Start
- Will error if any key is missing from any dictionary
- Will error if you try to create two sliders with one frame
- Will error if the holder does not have an AbsoluteSize and AbsolutePosition.
Example:
local newSlider = Slider.new(holderFrame, {
SliderData = {Start = 0, End = 10, Increment = 1, DefaultValue = 5},
MoveInfo = TweenInfo.new(0.1, Enum.EasingStyle.Quad),
Axis = "X",
Padding = 5
})
Slider:Track()
function Slider:Track()
Description: Starts the tracking system for the slider, and hooks up internal connections.
Parameters: None
Notes:
- This function should only be called once, it will reject any further calls until
:Untrack()
is called.
Example:
newSlider:Track()
newSlider:Track() -- This call will not run
Slider:Untrack()
function Slider:Untrack()
Description: Stops the tracking system for the slider and unhooks all internal connections.
Parameters: None
Notes:
- This function should only be called once, it will reject any further calls until
:Track()
is called. - This function will leave the slider in its last position.
Example:
newSlider:Untrack()
newSlider:Untrack() -- This call will not run
Slider:OverrideValue()
function Slider:OverrideValue(newValue: number)
Description: Overrides the Slider’s current value
Parameters:
Parameter | Type | Value |
---|---|---|
NewValue | Number | The new value to update the slider to. |
Notes:
- This will move the slider to the new position
- The
newValue
will get clamped to stay within the Slider’s bounds.
Example:
newSlider:OverrideValue(8)
Slider:OverrideIncrement()
function Slider:OverrideIncrement(newIncrement: number)
Description: Overrides the Slider’s current increment
Parameters:
Parameter | Type | Value |
---|---|---|
NewValue | Number | The new value to update the slider’s increment to. |
Notes:
- This will move the slider to the closest position relative to the increment
Example:
newSlider:OverrideIncrement(0.5)
Slider:GetValue()
function Slider:GetValue()
Description: Returns the slider’s current value.
Parameters: None
Notes: None
Example:
print("Current value:", newSlider:GetValue())
Slider:GetIncrement()
function Slider:GetIncrement()
Description: Returns the slider’s current increment.
Parameters: None
Notes: None
Example:
print("Current increment:", newSlider:GetIncrement())
Slider:Destroy()
function Slider:Destroy()
Description: Destroys the slider and removes it from the internal table. Disconnects all connections and signals.
Parameters: None
Notes:
- Any subsequent calls made to the slider after it’s destroyed will error.
Example:
newSlider:Destroy()
newSlider:Track() -- This call will error.
Connections
Slider.Changed
RBXScriptSignal: Slider.Changed
Description: Fires when the slider changes value.
Arguments:
Argument | Type | Value |
---|---|---|
NewValue | Number | The new value of the slider |
Notes:
- This event will fire along with
Slider.Dragged
Example:
Slider.Changed:Connect(function(newValue: Number)
print("Slider changed to " .. newValue)
end)
Slider.Dragged
RBXScriptSignal: Slider.Dragged
Description: Fires when the slider is dragged.
Arguments:
Argument | Type | Value |
---|---|---|
NewValue | Number | The new value of the slider |
Notes:
- This event will fire along with
Slider.Changed
Example:
Slider.Dragged:Connect(function(newValue: Number)
print("Slider was dragged and has value: " .. newValue)
end)
Slider.Released
RBXScriptSignal: Slider.Released
Description: Fires when the slider is released.
Arguments:
Argument | Type | Value |
---|---|---|
NewValue | Number | The new value of the slider |
Notes: None
Example:
Slider.Released:Connect(function(newValue: Number)
print("Slider was released and has value: " .. newValue)
end)
Example
FOV Slider
The Basics
Intro:
We’re going to create a slider which tweens the players Field of View.
Materials:
- Slider module
- Slider gui
Prep:
First, let’s create the slider gui, I’ve just created a simple gui with a TextButton named “Slider”
Slider.rbxm (6.3 KB)
Now with the gui created, we can import the Slider module, I prefer to import it into ReplicatedStorage
however you can put it wherever you wish.
Method:
With all the preparation done, we can move onto scripting the slider! Let’s begin!
I’m going to insert a script into the holder frame and call it SliderScript
(You can call it whatever, it doesn’t really matter).
Now let’s open the script and begin.
First off, we need to define some variables for this to work.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Slider = require(ReplicatedStorage:WaitForChild("Slider"))
local holderFrame = script.Parent
local currentCamera = workspace.CurrentCamera
What we’re doing here is simple, we first require the module which is located in ReplicatedStorage, and define a variable for the holder frame. We also define a variable for the camera because we need to update its field of view later on.
Next, we need to create our slider.
local FOVSlider = Slider.new(holderFrame, {
SliderData = {Start = 60, End = 110, Increment = 5},
MoveInfo = TweenInfo.new(0.1, Enum.EasingStyle.Quad)
})
Using the API above, we create a new slider and give the specified parameters. We want the FOV slider to start at 60, end at 110, and go up in increments of 5.
With the slider created, we now have to track when it changes and change the camera’s field of view!
Now, all that’s left to do is track the slider (this can be done with :Track()
!)
FOVSlider:Track()
If you run this, you should see that the slider now works!
That’s all for this tutorial! You can download a place file below.
FOVSlider.rbxl (55.7 KB)
Extra - Text and Tween (Optional).
Open Extra
You may have noticed that the FOV change doesn’t feel smooth, it feels quite clunky and jittery. To fix this we can add a tween to the camera, and for a little extra touch we can add some text to the button.
Now, for the script, it’s not too difficult to make, let’s follow this pseudocode.
--[[
When the slider updates value, we will check to see if a tween is running.
If a tween is running, cancel it and create a new one.
Once the new tween is created, we play it and move the camera.
We also need to update the text of the button whenever it's changed.
]]--
We can translate this into code quite easily.
Firstly, let’s update the .Changed
function to change the text of the slider.
FOVSlider.Changed:Connect(function(newFov: number)
workspace.CurrentCamera.FieldOfView = newFov
holderFrame.Slider.Text = math.floor(newFov)
end)
Now, let’s create a variable called currentTween
. This tween will be the current tween which plays and tweens the camera’s FOV.
Put this variable above the Changed function.
local currentTween = nil
Now, let’s update the .Changed
function to cancel the current tween (if there is one), and create a new one.
local currentTween = nil
FOVSlider.Changed:Connect(function(newFov: number)
if currentTween then
currentTween:Cancel()
end
currentTween = TweenService:Create(currentCamera, TweenInfo.new(0.5, Enum.EasingStyle.Quad), {FieldOfView = newFov})
currentTween:Play()
holderFrame.Slider.Text = math.floor(newFov)
end)
(Note above that TweenService must be defined)
Why are we cancelling the tween?
The reason we are creating a variable just for the current tween is so that tween’s don’t stack. Along with the fact that constantly creating and playing tweens can cause lag and fps drops. By cancelling the tween we make sure that we don’t stack them and that performance is as good as possible.
With that all done, we’re finished! You can experiment even more with this, and add your own features if you wish!
Finish
That’s the end of this resource! I hope you enjoyed reading about this as much as I did creating it. This is quite a scarce resource, as there are not a lot of complex features, however, I hope you all enjoy it!
- Krypt