Simple slider not working

I’m trying to create a simple sliding UI (click and drag a slider) I have seen some other documentation on how to make sliding UI on here, but a lot of them seem way too complicated for what I’m trying to achieve (Ie OOP, 100-200 lines of code)

local Container = script.Parent.Parent
local Slider = script.Parent

local Dragging

Slider.MouseButton1Down:connect(function()
	Dragging = true
end)

Slider.MouseButton1Up:connect(function()
	Dragging = false
end)

game:GetService("UserInputService").InputChanged:connect(function(InputObject, GameProcessedEvent)
	if ((not GameProcessedEvent) and Dragging) then
		if (InputObject.UserInputType == Enum.UserInputType.MouseMovement) then
			Slider.Position = UDim2.new(0, (InputObject.Position.X - Container.AbsolutePosition.X), 0, 0)
			if (Slider.AbsolutePosition.X < Container.AbsolutePosition.X) then
				Slider.Position = UDim2.new(0, 0, 0, 0)
			elseif (Slider.AbsolutePosition.X > (Container.AbsolutePosition.X + Container.AbsoluteSize.X)) then
				Slider.Position = UDim2.new(1, -Slider.AbsoluteSize.X, 0, 0)
			end
		end
	end
end)

Basic idea here (this is not my script). Problem I am currently facing can be shown below
com-video-to-gif
Moving to the right it clips, where as moving to the left it moves freely. And moving it all the way to the right it leaves the containers area. I want it to clip to each 0.1 on the scale (point being to control music volume, so 0 on the scale would be 0 volume, 0.4 scale = 0.4 volume, etc) up to 1

1 Like

The issue isn’t actually with the script as such, although there are a couple of things that need fixing there, too. The reason that the slider “snaps” is that your TextButton has the “Active” property set to true, which causes GameProcessedEvent to be true sometimes when moving the mouse while dragging, causing the position not to update.

Setting “Active” to false fixed it, but introduced another problem. The MouseButtonUp event doesn’t fire if you start dragging, but then let go of the mouse button when the cursor is outside the bounds of the TextButton.

Also, the math for limiting the slider to the extents of the container was wrong.

Here's a script with those issues fixed:
local InputService = game:GetService("UserInputService")

local Container = script.Parent.Parent
local Slider = script.Parent

local Dragging

Slider.MouseButton1Down:connect(function()
	Dragging = true
end)

InputService.InputEnded:Connect(function(inputObject)
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		Dragging = false
	end
end)

InputService.InputChanged:connect(function(InputObject, GameProcessedEvent)
	if ((not GameProcessedEvent) and Dragging) then
		if (InputObject.UserInputType == Enum.UserInputType.MouseMovement) then
			Slider.Position = UDim2.new(0, (InputObject.Position.X - Container.AbsolutePosition.X - Slider.AbsoluteSize.X/2), 0, 0)
			if (Slider.AbsolutePosition.X < Container.AbsolutePosition.X) then
				Slider.Position = UDim2.new(0, 0, 0, 0)
			elseif (Slider.AbsolutePosition.X > (Container.AbsolutePosition.X + Container.AbsoluteSize.X) - Slider.AbsoluteSize.X) then
				Slider.Position = UDim2.new(1, -Slider.AbsoluteSize.X, 0, 0)
			end
		end
	end
end)

Hope this helps, and let me know if you have any other issues with the slider.

This is pretty much exactly how I’ve implemented it in my own game, but we had to do some extra stuff for touchscreen devices to work with it, so if you need to support those devices and don’t know where to go, I can grab the code later today.

1 Like

Here’s one that will work nicely with touch devices, built upon @ThanksRoBama’s script:

local InputService = game:GetService( 'UserInputService' )

local Container = script.Parent.Parent
local Slider = script.Parent

local Dragging = false

Slider.MouseButton1Down:Connect( function ()
	Dragging = true
	-- If working with multiple sliders, here you'd set a value like
	-- SelectedSlider = Slider
end )

function SliderReleased()
	Dragging = false
	-- Perform any post-release actions, like saving the final slider position
	-- or update what it relates to if you didn't do live updates
end

InputService.InputEnded:Connect( function ( InputObject )
	if inputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		SliderReleased()
	end
end )

InputService.TouchEnded:Connect( function ( InputObject )
	SliderReleased()
end )

function MovedOnSlider( InputObject )
	-- If dealing with multiple sliders, here you'd reference SelectedSlider instead
	Slider.Position = UDim2.new( 0, ( InputObject.Position.X - Container.AbsolutePosition.X - Slider.AbsoluteSize.X / 2 ), 0, 0 )
	if Slider.AbsolutePosition.X < Container.AbsolutePosition.X then
		Slider.Position = UDim2.new( 0, 0, 0, 0 )
	elseif Slider.AbsolutePosition.X > ( Container.AbsolutePosition.X + Container.AbsoluteSize.X ) - Slider.AbsoluteSize.X then
		Slider.Position = UDim2.new( 1, -Slider.AbsoluteSize.X, 0, 0 )
	end

	-- Perform any live preview actions here
end

InputService.InputChanged:Connect( function( InputObject, GameProcessedEvent )
	if not GameProcessedEvent and Dragging and InputObject.UserInputType == Enum.UserInputType.MouseMovement then
		MovedOnSlider( InputObject )
	end
end )

InputService.TouchMoved:Connect( function ( InputObject, GameProcessedEvent )
	if not GameProcessedEvent and Dragging then
		MovedOnSlider( InputObject )
	end
end )
2 Likes