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