MouseLeave/MouseEnter have gotten significantly more reliable, but still have some remaining issues we’re working to fix:
- MouseEnter can sometimes fire before MouseLeave on the previous object.
- MouseEnter/MouseLeave fire for all objects under the cursor, instead of the one on top (and this is hard to fix without breaking games).
- Objects can get stuck in hovered state if they were the last hovered element when the mouse leaves the game window.
Currently, implementing your own draggable is a little complicated because of the need to bind to UserInputService, but I’m currently working on a change which will make it so that if you mouse down on a button, it will capture your mouse until you release the mouse button. This makes it very easy to implement sliders, scrollbars, and drag+drop because the only events you need are GuiObject’s InputBegan
, InputChanged
, and InputEnded
.
Here’s an old code snippet I wrote when Draggable got deprecated, which you can base your code off of in the mean time. This code should continue working after the changes above are shipped, but you won’t have to write as much code to implement dragging once those changes go live. This snippet uses the same strategy described by @Fm_Trick, but also handles touch input.
local UserInputService = game:GetService("UserInputService")
local gui = script.Parent
local dragging
local dragInput
local dragStart
local startPos
local function update(input)
local delta = input.Position - dragStart
gui.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
end
gui.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPos = gui.Position
input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
dragging = false
end
end)
end
end)
gui.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging then
update(input)
end
end)