[SOLVED] Help with snapping slider GUI at certain points

Hello! I’ve got 2 slider GUIs and they will both snap but they’ll both snap differently.

Below is my first slider GUI I’d like to snap. I’d like this to snap at each line (FOR, OFF, REV and ISOL) the code I currently have does work but it is not aligned properly and I’m horrible at math so I don’t know the correct way to get each point.

Here is the code for this part

local AbsolutePosition = DriveMode.Base.AbsolutePosition.Y
local AbsoluteSize = DriveMode.Base.AbsoluteSize.Y
		
local Number = math.clamp(math.floor((Y - AbsolutePosition) / AbsoluteSize / SNAPDISTANCE + 0.5) * SNAPDISTANCE, 0.159, 0.745)
DriveMode.Handle.Position = UDim2.new(0.586, 0, Number, 0)

For this one I did try to get the distance from FOR to ISOL and then divided it by 4 as the SNAPDISTANCE but that didn’t cut it and I’ve tried a few other ways and those also didn’t cut it.

image

And for my second slider GUI shown below I want it snap at every whatever the distance is between the MAXP and OFF or OFF and MINB line lets say this distance is 0.1 it’ll snap every 0.1 pixels? from MAXP to MAXB but from MAXB to EMERG it’ll just go straight from 1 to the other without snapping anywhere in between

Here is the code for this one

local AbsolutePosition = Throttle.Base.AbsolutePosition.Y
local AbsoluteSize = Throttle.Base.AbsoluteSize.Y

local Number = math.clamp(math.floor((Y - AbsolutePosition) / AbsoluteSize / SNAPDISTANCE + 0.5) * SNAPDISTANCE , 0.141, 0.913)
Throttle.Handle.Position = UDim2.new(0.542, 0, Number, 0)

For this one I tried to get the distance from MINP to OFF and then used that as the SNAPDISTANCE but that didn’t cut it and I’ve tried a few other ways and they also didn’t cut it.

image

Any help appreciated thanks!

One possible approach is to store all of the positions in a table, then find the closest position to the mouse. Distance in 1 dimension can be found with math.abs(mouseY-Position.Y).

I’m looking at the image I’ve used for the throttle guide in paint.net and for some spots I’ve actually made the distance a little bit bigger so if I make it smaller maybe it’ll work?

Each of the white smaller squares are where each point should be… and as you can see MAXP, MAXB and EMERG aren’t exactly on a point.

As for my other image all the points are correct and even.

But for the Throttle image could the problem be because each point isn’t even?

While moving the settings slightly so they coincide with the dots would definitely fix the problem. However, as with my last post, I would still recommend ditching your current method and storing all the positions of every setting (by setting I mean like MAXB or EMERG) then finding the closest point and snapping to it. In addition to fixing your problem, this prevents the slider from snapping onto nothing (the dots that don’t have anything on them would still be snapped to with your method.

If you’d like an example of a script that can do this, please let me know!

Yes please! That’d be awesome, I’m a little bit busy with another feature so some help would be awesome and probably time saving.

Thanks

Alright, here’s a script that can do this. The positions are not likely to work with your current image, so you’ll have to find them. Also, the image height must be updated. This is because I used the wrong image when creating this script.
Anyways, the script will automatically scale the position for bigger or smaller screens.

local uis = game:GetService("UserInputService")

local positions = {5,107,129,151,207,255}
local imageSize = 275 -- the height of the original image

local gui = script.Parent.ImageLabel -- the image of the settings
local sliderButton = gui.SliderButton -- the button that you slide to change settings

local function getNearestPos(pos:number) -- finds the nearest setting from a Y pos.
	local scale = gui.AbsoluteSize.Y/imageSize -- for scaling the positions
	
	local closest = nil
	for _,v in pairs(positions) do
		v *= scale -- scale the position to corrospond with the absolute size of the gui.
		if closest ~= nil and math.abs(pos-v) > math.abs(pos-closest) then continue end -- check if the distance between v and the last found closest position
		closest = v
	end
	return closest
end

local function convertMouseY(pos) -- makes the mouse's Y position relative to the top of the settings gui.
	local offset = 0
	
	if gui:FindFirstAncestor("ScreenGui").IgnoreGuiInset ~= true then -- not ignoring the Gui inset will offest the mouse by 36 pixels.
		offset = 36
	end
	print(pos,(pos-offset) - (gui.AbsolutePosition.Y))
	 return (pos-offset) - (gui.AbsolutePosition.Y)
end


-- For this demo I made it so it updates every frame (don't do this) and that you can click anywhere instead of on the slider to move it.
local mouseDown = false

uis.InputBegan:Connect(function(i,gp)
	if gp or i.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
	mouseDown = true
end)
uis.InputEnded:Connect(function(i)
	if i.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
	mouseDown = false
end)

game:GetService("RunService").RenderStepped:Connect(function() -- update pos every frame for simplicity's sake.
	if mouseDown == false then return end
	
	local mouseRelativeToGui = convertMouseY(uis:GetMouseLocation().Y)
	local snappedPos = getNearestPos(mouseRelativeToGui)
	
	-- this uses offset for positioning the button, however you could easily convert them to scale.
	sliderButton.Position = UDim2.new(sliderButton.Position.X.Scale,sliderButton.Position.X.Offset,0,snappedPos)
end)

Please reply if you have any questions, and good luck!

Thank you! I’ll give this a try tonight and I’ll give you a reply.

Hello!

Sorry for the late reply, I’ve only just tried your solution last night, however it didn’t exactly work well for me but fortunately I’ve figured it out less than an hour ago and it works perfectly!

Thank you anyways!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.