GUI dragging is offset

Hello, I’m making a sort of map with player tracking and all but I’m coming across this issue; when a player clicks on the gui, the gui is supposed to follow the mouse and allow for panning of the map itself. This part is working however it is offset for whatever reason! Here’s a couple pictures for reference, the anchor point is not the issue and I’d rather not use an offset but rather the position of the image label itself.



image

Here’s the explorer;
image
The problem part of the script;

local function movemap()
	while true do
		wait(.01)
		if held == true then
			script.Parent.Position = UDim2.new(0,mouse.X,0,mouse.Y)
			print("updated")
		end
	end
end

And finally the full script;

script.Parent.MouseWheelForward:Connect(function()
	script.Parent.Size = script.Parent.Size + UDim2.new(0,50,0,50)
end)

script.Parent.MouseWheelBackward:Connect(function()
	script.Parent.Size = script.Parent.Size - UDim2.new(0,50,0,50)
end)


local held = false
local mouse = game.Players.LocalPlayer:GetMouse()

local function movemap()
	while true do
		wait(.01)
		if held == true then
			script.Parent.Position = UDim2.new(0,mouse.X,0,mouse.Y)
			print("updated")
		end
	end
end

script.Parent.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		held = true
		movemap()
	end
end)

script.Parent.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		held = false
	end
end)

Is the size of the GUI scaled or offsetted? You can check in the frame’s properties.

I assume by scaled you mean sized but yeah, it’s just sized.
image

Yep, the reason it’s not working is because it’s set to offset in the size.
If you expand the size property it will show you
image

Change it to {0,0}, {0,0} and then you can resize it on screen to whatever size you want so it’s scaled on all devices and uses Scale rather than Offset

You need to subtract the absolute position of the parent frame from your position.

Thank you for this, I can never figure if it’s scale or offset, but the problem does still remain and the dragging is still offset.

Have you tried changing it from offset to scale in your other image labels / frames?

Do you mean subtract the position of the image’s parent?

Yes, while setting the position, subtract the mouses position with the parents AbsolutePosition property.

This is getting closer but it’s not exactly what I want, I want it to drag from where the mouse cursor is, this makes it drag by the corner.

If it helps at all the frame that has the image is not moving at all and shouldn’t be, I want just the image to move.

Then you need to also get the offset from the objects absolute position. Basically, before you start moving, see where the mouse is and then subtract the guis absolute position from it, then just add it to the final position while setting.

Something like:

local offset = mousePosition - script.Parent.AbsolutePosition
-- loop Please use RunService loops!!
local position = mousePosition-script.Parent.Parent.AbsolutePosition + offset
script.Parent.Position = UDim2.fromOffset(position.X,position.Y)
script.Parent.Position = UDim2.new(0,mouse.X,0,mouse.Y) - UDim2.new(0,script.Parent.Parent.AbsolutePosition.X,0,script.Parent.Parent.AbsolutePosition.Y) + UDim2.new(0,script.Parent.AbsolutePosition.X,0,script.Parent.AbsolutePosition.Y)

You mean something like this? If so, it’s not working and offsets crazy

I recommend UserInputService for getting the mouse position.

When the mouse is clicked, store the mouse’s current position.

local lastMousePosition = UserInputService:GetMouseLocation()

Let’s also store the current position of the map as a Vector2

local mapPosition = script.Parent.Position
local mapPositionAsVector2 = Vector2.new(mapPosition .X.Offset, mapPosition .Y.Offset)

Then, while the mouse is down, listen to the mouse movement:

-- not using while loops.
UserInputService.InputEnded:Connect(function(inputObject, gameProcessed)
	if (gameProcessed or not held) then return end -- if the input is processed by the Roblox UI, or if the button is not held.
	
	
	if (inputObject.UserInputType ~= Enum.UserInputType.MouseMovement) then
		return -- we only want UserInputType.MouseButton1. anything else is discarded.
	end
	
	-- either GetMouseLocation or inputObject.Position
	local mapOffsetDelta = UserInputService:GetMouseLocation() - lastMousePosition
	local newMapPosition = mapPositionAsVector2 + mapOffsetDelta

	script.Parent.Position = UDim2.new(0, newMapPosition.X, 0,newMapPosition.Y)
end)

I’ve tried this before, unfortunately it’s for a GUI and it registers something different instead of a normal click or something, I’m not entirely sure how it all works but it didn’t work nor did your code with the obvious edits.

I don’t understand that. UIS is meant for all GUIs including your map view. How did you set up your code with my example?

Basically a copy and paste, exactly how you put it. I’ve re-implemented it from deleting it because it didn’t do anything and doesn’t even print past the first check that sees if it’s interacted with anything.

UserInputService.InputEnded:Connect(function(inputObject, gameProcessed)
	print("yep")
	if (gameProcessed or not held) then return end -- if the input is processed by the Roblox UI, or if the button is not held.
	print("yep2")
	if (inputObject.UserInputType ~= Enum.UserInputType.MouseButton1) then
		return -- we only want UserInputType.MouseButton1. anything else is discarded.
	end
	print("yep3")
	-- either GetMouseLocation or inputObject.Position
	local mapOffsetDelta = UserInputService:GetMouseLocation() - mapPositionAsVector2
	local newMapPosition = mapPositionAsVector2 + mapOffsetDelta

	script.Parent.Position = UDim2.new(0, newMapPosition.X, 0,newMapPosition.Y)
end)

Here’s what the output yeilds;
image

Sorry, haha, I just realized it’s inputended and not inputbegan, I switched and will be messing with it, I’ll update you.

Well it still doesn’t do anything but prints “yep” twice, I’m at a loss.

The code is meant to be connected to InputChanged.

Also, I think I understand why you might be confused with UIS. The InputBegan, InputChanged, and InputEnded events return an InputObject. You can separate different logic with different inputs by comparing InputObject.UserInputType to an Enum.UserInputType.

For left-click logic, use Enum.UserInputType.MouseButton1 with InputBegan or InputEnded. For scroll-wheel logic, use Enum.UserInputType.MouseWheel with InputChanged.