Needing Help to Set Frame's Anchor Point to Mouse's AbsolutePosition (Immediate & Logical Assistance Required)

Alright, so I’m trying to make this draggable GUI frame, and here’s my code,

local e = false
script.Parent.MouseEnter:Connect(function()
	e = true
end)
script.Parent.MouseLeave:Connect(function()
	e = false
end)
local er = false
local mou = game.Players.LocalPlayer:GetMouse()
mou.Button1Down:Connect(function()
	script.Parent.AnchorPoint=Vector2.new(((workspace.CurrentCamera.ViewportSize.X/script.Parent.AbsoluteSize.X)*mou.X)/workspace.CurrentCamera.ViewportSize.X,((workspace.CurrentCamera.ViewportSize.Y/script.Parent.AbsoluteSize.Y)*mou.Y)/workspace.CurrentCamera.ViewportSize.Y)
	if e==true then
		er = true
	else
		er = false
	end
end)
mou.Button1Up:Connect(function()
	er = false
end)
while wait(.1/2) do
	if er==true then
		game:GetService("TweenService"):Create(script.Parent,TweenInfo.new(.3,Enum.EasingStyle.Quint),{Position=UDim2.new((mou.X)/workspace.CurrentCamera.ViewportSize.X,0,(mou.Y)/workspace.CurrentCamera.ViewportSize.Y,0)}):Play()
	end
end

I can’t seem to wrap my head around the equation to set the anchor point of the frame to the mouse’s position. I want the anchor point to be where the mouse is relative to the frame, so that the centre of translation is where the mouse is. Here’s a video, and what’s shown is not what I want

try presetting the anchor point to (0.5, 0.5) and just changing the positions

local e = false
script.Parent.MouseEnter:Connect(function()
	e = true
end)
script.Parent.MouseLeave:Connect(function()
	e = false
end)
local er = false
local mou = game.Players.LocalPlayer:GetMouse()
script.Parent.AnchorPoint = Vector2.new(0.5, 0.5)
mou.Button1Down:Connect(function()
	if e==true then
		er = true
	else
		er = false
	end
end)
mou.Button1Up:Connect(function()
	er = false
end)
while wait(.1/2) do
	if er==true then
		local posX = (mou.X)/workspace.CurrentCamera.ViewportSize.X
		local posY = (mou.Y)/workspace.CurrentCamera.ViewportSize.Y
		local pos = UDim2.fromScale(posX, posY)
		game:GetService("TweenService"):Create(script.Parent,TweenInfo.new(.3,Enum.EasingStyle.Quint),{Position=pos}):Play()
	end
end

That’s not the point. I want the anchor point to be wherever my cursor on the frame is. Not the middle.

I have an example of what I don’t want.
So say, you have a viewportframe of 1920x1080


Your mouse is positioned where the red part is, and the math you use makes it scaled to the absolute size of the frame, plus the absolute position of the frame minus the absolute size of the frame times the previous absolute position

Now if you just divide that by the absolute size of the frame, and make that the anchorpoint, you end up with this.
It’s not the same position.

IF I follow your directions, it still wouldn’t be it. Take a look at this behavior.
This is exactly what I didn’t want in the first place.

Been 4 days and still haven’t figured anything out. A little help here would be nice. Feels like I’m being purposefully ignored

Maybe set the mouse icon to the position since setting the mouse icon will make the mouse follow.

And then obviously set the mouse cursor back to normal.

I ran into this problem a bit ago and it took me a long time to solve. Here is what I did:

	local function update(input)
		local delta = input.Position - clickPos
		guiObject.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
	end
	

UserInputService.InputChanged:Connect(function(input)
		if input == dragInput and draggingGui then
			update(input)
		end
		if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
			dragInput = input
		end
	end)

Let me know if you need further help but this piece of code might be what you’re looking for.

Ah, so anchorpoints were completely unnecessary

1 Like

Yep pretty much. My last response was rushed but I put together a more readable script. Just put this script inside your frame.

local UserInputService = game:GetService("UserInputService")

local function MakeGuiDraggable(guiObject)
	local draggingGui
	local dragInput
	local clickPos
	local startPos

	local function update(input)
		local delta = input.Position - clickPos
		guiObject.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
	end


	guiObject.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			draggingGui = true
			clickPos = input.Position
			startPos = guiObject.Position
		end	
	end)

	UserInputService.InputEnded:Connect(function(input, gpe)
		if gpe then return end
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			if draggingGui then
				draggingGui = false
				clickPos = nil
				startPos = nil
			end
		end
	end)

	guiObject.InputChanged:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
			dragInput = input
		end
		
		if input == dragInput and draggingGui then
			update(input)
		end
	end)
end

MakeGuiDraggable(script.Parent)

https://gyazo.com/53a41277507ad3037e42ab2c0ef1cc01

Made some changes to the script and here is a place if you want to test it out:
DraggableGui.rbxl (31.0 KB)

That’s a little rude don’t you think.

5 Likes

Can you rewrite this code but only use Scale?
I’ve tried it and it doesn’t work for me.

While using AnchorPoint is tedious and pointless, I’m gonna use a way easier and professional version.
*Node: it doesn’t invole tweening.
*Node2: NOT PERFECT!!

-- Put this localscript parented to your frame
local cas = game:GetService("ContextActionService")
local frame = script.Parent

local mouseInside = false
local delta = Vector2.new()
local mousePos = Vector2.new()
local btn1 = false -- button 1 isnt pressed

local mouseBehaviourStage = 2 -- needed to aboid bugging when still dragging outside window
-- 1 = begin, 2 = change, 3 = end

function moveWindow(name, input, obj)
	if obj.UserInputState == Enum.UserInputState.Begin then -- mb1 down
		if mouseBehaviourStage == 2 then
			btn1 = true
			delta = frame.AbsolutePosition - mousePos
		elseif mouseBehaviourStage == 3 then
			btn1 = false
			mouseInside = false
		end
		mouseBehaviourStage = 1
		
	elseif obj.UserInputState == Enum.UserInputState.End then -- mb1 up
		btn1 = false
		mouseBehaviourStage = 3
		
	elseif obj.UserInputState == Enum.UserInputState.Change then -- mouse move
		if mouseBehaviourStage ~= 3 then
			mousePos = Vector2.new(obj.Position.X,obj.Position.Y)
			if mouseInside and btn1 then
				local result = mousePos + delta
				frame.Position = UDim2.new(0,result.X,0,result.Y)
			end
		end
		mouseBehaviourStage = 2
	end
end

cas:BindAction("mouseBehaviour", moveWindow, false, Enum.UserInputType.MouseMovement, Enum.UserInputType.MouseButton1)


frame.MouseEnter:Connect(function()	mouseInside = true end)
frame.MouseLeave:Connect(function() if not btn1 then mouseInside = false end end)