Draggable GUI causes a noticeable offset

Hello Developers!

I’ve encountered an issue while making draggable GUI which in the title says, the GUI for some reason has a noticeable offset.

--//Services
local UIS = game:GetService("UserInputService")
--//Frame
local Frame = script.Parent
--//Variables
local Camera = workspace:WaitForChild("Camera")
local Draggable = false
--
local DragMovePos
local FramePos
local Clone
--//Func
Frame.InputBegan:Connect(function(i)
	if i.UserInputType == Enum.UserInputType.MouseButton1 then
		Draggable = true
		Clone = Frame:Clone()
		Clone.Parent = Frame.Parent.Parent
		
		DragMovePos = Vector2.new(i.Position.X, i.Position.Y)
		FramePos = Vector2.new(Clone.Position.X.Scale, Clone.Position.Y.Scale)
	end
end)

Frame.InputEnded:Connect(function(i)
	if i.UserInputType == Enum.UserInputType.MouseButton1 then
		Draggable = false
		Clone:Destroy()
	end
end)

UIS.InputChanged:Connect(function(i)
	if Draggable == true then
		local NewPos = FramePos + ((Vector2.new(i.Position.X, i.Position.Y) - DragMovePos) / Camera.ViewportSize)
		Clone.Position = UDim2.new(NewPos.X, 0, NewPos.Y, 0)
	end
end)
2 Likes

The problem lies in how you are calculating the new position of the Clone frame. You are adding the difference between the current mouse position and the initial click position directly to FramePos , which is incorrect.

Script:

--//Services
local UIS = game:GetService("UserInputService")

--//Frame
local Frame = script.Parent

--//Variables
local Camera = workspace:WaitForChild("Camera")
local Draggable = false

local DragStartPos
local FrameStartPos
local Clone

--//Func
Frame.InputBegan:Connect(function(i)
	if i.UserInputType == Enum.UserInputType.MouseButton1 then
		Draggable = true
		Clone = Frame:Clone()
		Clone.Parent = Frame.Parent.Parent

		DragStartPos = i.Position
		FrameStartPos = Clone.Position
	end
end)

Frame.InputEnded:Connect(function(i)
	if i.UserInputType == Enum.UserInputType.MouseButton1 then
		Draggable = false
		Clone:Destroy()
	end
end)

UIS.InputChanged:Connect(function(i)
	if Draggable then
		local DragDelta = i.Position - DragStartPos
		local NewPos = UDim2.new(
			FrameStartPos.X.Scale,
			FrameStartPos.X.Offset + DragDelta.X,
			FrameStartPos.Y.Scale,
			FrameStartPos.Y.Offset + DragDelta.Y
		)
		Clone.Position = NewPos
	end
end)

I’ve made adjustments to how the new position is calculated. It now takes into account both the scale and offset components of the original position. This should eliminate the noticeable offset issue you were experiencing.

1 Like

It doesn’t work sadly

{Filler}

script:

local UIS = game:GetService("UserInputService")
 
local draggableFrame = script.Parent
 
local IsDragging = false
local dragInput 
local StartingPoint
local oldPos 
 
local function update(input)
    local delta = input.Position - StartingPoint
    draggableFrame.Position = UDim2.new(oldPos.X.Scale, oldPos.X.Offset + delta.X, oldPos.Y.Scale, oldPos.Y.Offset + delta.Y)
end
 
draggableFrame.InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
        IsDragging = true
        StartingPoint = input.Position
        oldPos = draggableFrame.Position
 
        input.Changed:Connect(function()
            if input.UserInputState == Enum.UserInputState.End then
                IsDragging = false
            end
        end)
    end
end)
 
draggableFrame.InputChanged:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseMovement then
        dragInput = input
    end
end)
 
UIS.InputChanged:Connect(function(input)
    if input == dragInput and IsDragging then
        update(input)
    end
end)
1 Like

It works! Thanks very much!

{Filler}

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