Hello! Can someone please help me and say, why mouse.Button1Up:Wait()
don’t stop waiting?
mouse is game:GetService("Players").LocalPlayer:GetMouse()
while true do
print("Active")
Scroller.MouseButton1Down:Wait()
print("MouseIsDown")
local Offset = mouse.X - Scroller.AbsolutePosition.X - (Scroller.AbsoluteSize.X / 2) + ScrollerBar.AbsolutePosition.X
local Connection = mouse.Move:Connect(function()
print("MouseMoved")
local PosX = mouse.X
Scroller.Position = UDim2.new(math.clamp((PosX - Offset) / ScrollerBar.Size.X.Offset, 0, 1), 0, 0.5, 0)
Text.Text = if math.clamp((PosX - Offset) / ScrollerBar.Size.X.Offset, 0, 1) == 0 and Values[1] == "Dis." then "Dis." else tostring(math.round(math.clamp((PosX - Offset) / ScrollerBar.Size.X.Offset, 0, 1) * (Values[2] - (if Values[1] == "Dis." then 0 else Values[1]))) + 1)
end)
mouse.Button1Up:Wait() -- The problem
print("MouseReleased")
Connection:Disconnect()
end
1 Like
try putting a print() inside the :Wait()
Now, it prints “MouseUp” when Scroller.MouseButton1Down
finishes waiting…
mouse.Button1Up:Wait(print("MouseUp"))
Change the wait to :Connect(function() then put a task.wait and put print(“Mouse Released”)
The problem is that player can click this scroller button many times, and every click it will create 1 unneeded function, which will lag player.
Also, if I change mouse.Button1Up:Wait()
to Scroller.MouseButton1Up:Wait()
all works perfectly with connections, but not so perfect when mouse leaves button.
You should just use a Changed Connect event with a debounce to avoid the lag. You could do a seperate function with a spawned task, if you prefer that as well.
It sounds like you’re only wanting to change something when the player is dragging a button. To achieve this, I would suggest that you connect to events rather than use a loop with :Wait()
s for events. I say this because the behavior of the events is more reliable in this format. You can achieve this with the following:
local button = script.Parent
local isPressingButton = false
button.InputBegan:Connect(function()
isPressingButton = true
end)
button.InputEnded:Connect(function()
isPressingButton = false
end)
local userInputService = game:GetService("UserInputService")
userInputService.InputChanged:Connect(function(inputObject)
if inputObject.UserInputType==Enum.UserInputType.MouseMovement and isPressingButton then
--inputObject.Position is the mouse's current position!
print("Dragging! ", inputObject.Position)
end
end)
I’m using InputBegan and InputEnded because they’re more reliable than the MouseButton1Down and MouseButton1Up events. I’m using UserInputService.InputChanged to detect when the mouse moves when the player has one of their mouse buttons down. If I used GuiObject.InputChanged, it wouldn’t fire when the mouse leaves the button, which is something I don’t think you want.
Yes, with the code above you can drag with any of the mouse buttons, including the scroll wheel button. If you don’t want that, then you can do this for both the InputBegan and InputEnded parts:
button.InputBegan:Connect(function(inputObject)
if inputObject.UserInputType==Enum.UserInputType.MouseButton1 then
isPressingButton = true
end
end)
button.InputEnded:Connect(function(inputObject)
if inputObject.UserInputType==Enum.UserInputType.MouseButton1 then
isPressingButton = false
end
end)
1 Like
I tried something like this, but I mean connecting 100 functions that triggers every mouse movement isn’t optional. Also you guessed what I want achieve.
BUT:
But my question consist of WHY mouse.Button1Up:Wait()
don’t work, but Scroller.MouseButton1Up:Wait()
works fine? (Scroller = TextButton)
There’s two scenarios that I can think of that would cause a problem with relying on Button1Up. One pontential scenario is that Button1Up fires before you :Wait() for it. The other scenario is that it simply isn’t firing considering that the Mouse object has been superseded by UserInputService (which is what my snippet uses).
I wouldn’t call my snippet not optimal considering it’s not running the functions constantly. The only one that is running when it doesn’t need to be is the UserInputService.InputChanged event’s function. If you really want it not always listening to that event, then you do something like this:
local button = script.Parent
local mouseInputConnection = nil
button.InputBegan:Connect(function(inputObject)
if inputObject.UserInputType~=Enum.UserInputType.MouseButton1 then
return
end
if mouseInputConnection==nil then
local userInputService = game:GetService("UserInputService")
mouseInputConnection = userInputService.InputChanged:Connect(function(inputObject)
if inputObject.UserInputType==Enum.UserInputType.MouseMovement then
--inputObject.Position is the mouse's current position!
print("Dragging! ", inputObject.Position)
end
end)
end
end)
button.InputEnded:Connect(function(inputObject)
if inputObject.UserInputType~=Enum.UserInputType.MouseButton1 then
return
end
if mouseInputConnection then
mouseInputConnection:Disconnect()
mouseInputConnection = nil
end
end)
This type of pattern is extremely common and probably the recommended pattern to use for stuff like this. I have never seen anyone use a while-loop for something like this, nor would I recommend doing something like that for what you’re trying to do.
Edit:
I should probably mention this, but if you want the snippet above to work with touch enabled devices, you’ll need to add another part to the if statement like:
or inputObject.UserInputType~=Enum.UserInputType.Touch
Not only that, but you might need to use UserInputService:GetMouseLocation() in a RunService.Hearbeat event instead of using UserInputService.InputChanged.
1 Like