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)
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.
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)