Set position to the exact position

I’m creating a drag-and-drop system but the position is not correct. It would be offset far away.

Code:

local UserInputService = game:GetService("UserInputService")

local gui = script.Parent
local List = gui:WaitForChild("List")
local Template = gui:WaitForChild("Template")

local isDragging = false
local dragInput
local dragStart
local startPos

local currentGui

local function CreateNew()
	currentGui = Template:Clone()
	currentGui.Visible = true
	currentGui.Parent = gui
end

local function UpdateDragging(input)
	if currentGui then
		local parentPos = currentGui.Parent.AbsolutePosition
		local delta = input.Position - dragStart
		local newPosition = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
		currentGui.Position = newPosition
	end
end

for i,v in ipairs(List:GetChildren()) do
	if v:IsA("Frame") then
		v.InputBegan:Connect(function(input)
			if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
				isDragging = true
				dragStart = input.Position
				startPos = v.Position
				currentGui = v
				
				CreateNew()
				
				input.Changed:Connect(function()
					if input.UserInputState == Enum.UserInputState.End then
						isDragging = false
					end
				end)
			end
		end)

		v.InputChanged:Connect(function(input)
			if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
				dragInput = input
			end
		end)
	end
end

UserInputService.InputChanged:Connect(function(input)
	if input == dragInput and isDragging then
		UpdateDragging(input)
	end
end)

1 Like

Try changing this line to the following:

local newPosition = UDim2.new(0, startPos.X.Offset + delta.X, 0, startPos.Y.Offset + delta.Y)

I think the issue might be the fact that you are setting both the scale and the pixel offset, usually you would set one and leave the other as zero.

Yes, but the positioning would still be wrong.

Try changing this:

startPos = v.Position

To this:

startPos = dragStart
1 Like

Seems to work but it doesn’t seem to drag it by the origin of the startPos:

local function UpdateDragging(input)
	if currentGui then
		local parentPos = currentGui.Parent.AbsolutePosition
		local delta = input.Position - dragStart
		local newPosition = UDim2.new(0, startPos.X + delta.X, 0, startPos.Y + delta.Y)
		currentGui.Position = newPosition
	end
end

for i,v in ipairs(List:GetChildren()) do
	if v:IsA("Frame") then
		v.InputBegan:Connect(function(input)
			if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
				isDragging = true
				dragStart = input.Position
				startPos = dragStart
				currentGui = v

				CreateNew()

				input.Changed:Connect(function()
					if input.UserInputState == Enum.UserInputState.End then
						isDragging = false
					end
				end)
			end
		end)

		v.InputChanged:Connect(function(input)
			if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
				dragInput = input
			end
		end)
	end
end

Change the anchor of the red frame to (0.5, 0.5)

I meant something like this: