How would i make a text button work like a iPod scroll wheel. I’m not good with math. It has 10 points, and functions for “Counterclockwise” and “Clockwise”. it is gonna be used to go up and down a list of items. Since there’s 10 points, if for example, I scroll around the wheel 1 and a half times going clockwise, that would be positive 15 points, and that would fire the "Clockwise" function 15 times, only problem is, I don’t know how to figure this part out. Any help is very appreciated. Thank you
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local wheel = script.Parent:WaitForChild("Wheel")
local points = 10
local function Counterclockwise() -- aka go up 1
print("Up")
end
local function Clockwise() -- aka go down 1
print("Down")
end
local scrolling = false
local startPoint = nil -- the point (1-10) at which the player begins scrolling on the wheel
wheel.MouseButton1Down:Connect(function()
scrolling = true
repeat
task.wait()
-- code here
until scrolling == false
end)
wheel.MouseButton1Up:Connect(function()
scrolling = false
startPoint = 0
end)
wheel.MouseLeave:Connect(function()
scrolling = false
startPoint = 0
end)
I assume you mean that you want to be able to press down (Left mouse button) on a TextButton, and move your mouse around in a circle inside the button to emulate scrolling like on the old iPod you showed.
For starters, you can check what the mouse’s position is while pressing down.
And on each frame, you look at how the mouse moves.
So you’d get a direction vector telling you which way the mouse is moving.
Then, you have to check if the direction of mouse movement is tangent to the circle inside your button.
I quick drew this to try to illustrate what I mean.
Solving this requires a basic understanding of Vectors. Which isn’t that difficult of a thing to learn. It’s just a group of numbers (though, there is more to learn about it than just that).
Also, you will need to know a bit about math.sin and math.cos.
Also known as “sine” and “cosine”. Both of those are used to get a point on a circle, given an angle.
You will also need to know about a function called “dot product” which can be used to compare the direction of 2 vectors. This is needed for your circular scrolling because you need to compare the movement of your mouse is tangent to the wheel itself. And you can get a vector which is tangent to the circle, and you would use that to compare against your mouse movement vector. To determine if the mouse movement is moving around the circle properly.
I will also give you these things to read as well. As they are important.
local rs = game:GetService('RunService')
local mouse = game.Players.LocalPlayer:GetMouse()
local btn = script.Parent
local connection
local interval = 10
local currentAngle = 0
local lastAngle
local lastCurrentAngle = 0
local scrollIndex = 0
local lastScrollCount
local intervalDone = false
local center = btn.AbsolutePosition + btn.AbsoluteSize / 2
local inputEnums = {
MouseButton1 = true,
Touch = true
}
btn.InputBegan:Connect(function(input)
if not inputEnums[input.UserInputType.Name] then return end
local initialAngle = 0
local lastInterval = 0
lastAngle = math.atan2(mouse.Y - center.Y, mouse.X - center.X)
connection = rs.RenderStepped:Connect(function()
local angle = math.atan2(mouse.Y - center.Y, mouse.X - center.X)
if not angle or not lastAngle then return end
local deltaAngle = angle - lastAngle
deltaAngle = math.deg(deltaAngle - (deltaAngle > math.pi and 2 or -2) * math.pi)
currentAngle = (currentAngle + deltaAngle + 360) % 360
initialAngle = (initialAngle + deltaAngle + 360) % 360
local currentInterval = math.floor(currentAngle / (360/interval))
if lastInterval ~= currentInterval then
if currentAngle == lastCurrentAngle then return end
local angleDiff = (currentAngle - lastCurrentAngle + 360) % 360
if angleDiff > 180 then
scrollIndex -= 1
print(scrollIndex)
else
scrollIndex += 1
print(scrollIndex)
end
end
lastInterval = currentInterval
lastAngle = angle
lastCurrentAngle = currentAngle
end)
end)
btn.InputEnded:Connect(function(input)
if not inputEnums[input.UserInputType.Name] then return end
if connection then
connection:Disconnect()
connection = nil
end
lastAngle = nil
end)
Basically first of all you get the centerpos of the gui and mouse pos and given:
local GUI = -- path to spinny boi gui
local CenterPosition = GUI.AbsolutePosition+GUI.AbsoluteSize/2
local MousePosition = UserInputService:GetMouseLocation()
local function GetRotation()
local difference = CenterPosition-MousePosition
return math.deg(math.atan2(difference.Y,difference.X))
end
local function CalculateRotationDirection()
local difference = GUI.Rotation-GetRotation()
if difference > 0 then
return "Clockwise"
else
return "Anti-Clockwise"
end
end
Then you find the rotation of the gui to the mouse position and then you need to find the direction of motion which I gave above. Now you can accordingly do your thing. That being I suppose:
local GUI = -- path to spinny boi gui
local CenterPosition = GUI.AbsolutePosition+GUI.AbsoluteSize/2
local MousePosition = UserInputService:GetMouseLocation()
local function GetRotation()
local difference = CenterPosition-MousePosition
return math.deg(math.atan2(difference.Y,difference.X))
end
local function CalculateRotationDirection()
local difference = GUI.Rotation-GetRotation()
return difference > 0 and -1 or 1
end
local value = 0
local function SpinGui()
local direction = CalculateRotationDirection()
GUI.Rotation = GetRotation()
value += direction
end
GUI.MouseButton1Down:Connect(function()
-- bla bla bla scrolling thingy
end)
He didn’t ask for how to rotate the button, he asked how to make a scrolling function similar to the iPod’s touch wheel (e.g clockwise +1 counter clockwise -1) when you move your mouse around it.
local rotation = 0
local function CalculateRotationDirection()
local difference = rotation-GetRotation()
return difference > 0 and -1 or 1
end
local value = 0
local function SpinGui()
local direction = CalculateRotationDirection()
rotation = GetRotation()
value += direction
end
He’s asking for something that isn’t even in your solution. If you see his attempt he’s got variables of the startpoint and scrolling index including lines that say local function Counterclockwise() -- aka go up 1.
You know how the iPod’s scroll wheel works right, you move your finger clockwise around the wheel, you scroll down and vice versa. He’s asking how to make something like this with a TextButton where if you move your mouse clockwise and counterclockwise around the gui it scrolls. He’s already started with a scroll index variable which he wants to increase or decrease based of the clockwise/counter-clockwise.
The gui shouldn’t rotate since it’s a ipod wheel (right?).
local wheel = script.Parent.Wheel
local CenterPosition = GUI.AbsolutePosition+GUI.AbsoluteSize/2
local UIS = game:GetService("UserInputService")
local function GetRotation(Pos1,Pos2)
local MousePosition = UIS:GetMouseLocation()
local difference = Pos1-Pos2
return math.deg(math.atan2(difference.Y,difference.X))
end
local function CalculateRotationDirection(StartPosition)
local difference = GetRotation(CenterPosition,StartPosition)-GetRotation(CenterPosition,MousePosition)
return difference > 0 and -1 or 1
end
local function Counterclockwise() -- aka go up 1
print("Up")
end
local function Clockwise() -- aka go down 1
print("Down")
end
local scrolling = false
local startPoint = nil
wheel.MouseButton1Down:Connect(function()
scrolling = true
startpoint = UIS:GetLocation()
repeat
task.wait()
if CalculateRotationDirection(startpoint) > 1 then
Counterclockwise()
else
Clockwise()
end
until scrolling == false
end)
wheel.MouseButton1Up:Connect(function()
scrolling = false
startPoint = 0
end)
wheel.MouseLeave:Connect(function()
scrolling = false
startPoint = 0
end)
I wrote this in the forum so pardon me if any mistakes are made : p.
okay thank you it works really well except when i scroll past the top of the scroll wheel it subtracts by 1 when im scrolling clockwise and vice versa. do you know how to fix this?
I tried fixing it but no matter what I do it doesn’t help. I believe it’s a floating point error and you can’t really avoid that in this case since you have to divide regardless of rounding or not.
This is actually a fun project so I’ll see if I can fix it later.
What I would do for now is remove the math.floor from the currentInterval that way it’s the raw numbers then print out the currentInterval inside the if currentAngle ~= lastCurrentAngle scope. See what the 9th number prints out.
There are two things I believe could be the problem, either:
floating point decimals
initialAngle fluctuating due to the % operator used beforehand.
Is this the 9th? I’m assuming these are negatives as they go down. do a few more tests see if the results are consistent. It’s strange how this same pattern happens EXACTLY for the first cycle regardless you’re going clockwise or counter clockwise. I noticed how close the 9th one is to 10, 9.98 is a really close number
ive noticed it usually triggers the opposite, in this case, counterclockwise (up), right when i scroll around the wheel once and scroll past where i started, so once ive gone around once
it prints out different every time
in this pic, ive gone around the wheel once clockwise and right as i go past where i started, the highlighted area, it prints “up”, aka counterclockwise
Yeah, the pattern only happens on the first cycle but then after that it’s more of random. Try rounding out the initialAngle before you do any of the currentinterval calcs