As the title says, I’ve attempted to logically create a UI specific draggable UI script. UI specific I mean a script that only works for my frame.
As long as the I am holding either Mouse 1 or Mouse 2 buttons Navigation, it counts the difference between the current and the original X and Y vectors of the mouse. Add an additional offset to these two values to center it (according to the ascending Frame) and move it. But there is a bug, which makes the Frame go down and right decently fast, and the movement doesn’t stop when I release either button I originally pressed.
Here’s my code:
local M = game.Players.LocalPlayer:GetMouse();
local RunService = game:GetService("RunService");
local active = false;
local save = false;
local mX, mY
local Navigation = script.Parent:WaitForChild("Title");
local Frame = script.Parent.Parent;
Navigation.MouseButton1Down:Connect(function() active = true end);
Navigation.MouseButton2Down:Connect(function() active = true end);
Navigation.MouseButton1Up:Connect(function() active = false end);
Navigation.MouseButton2Up:Connect(function() active = false end);
Navigation.MouseLeave:Connect(function() active = false end);
RunService.Stepped:Connect(function()
if active == true then
print("activate")
if save == false then
mX, mY = M.X, M.Y;
save = true;
print("saved")
end
local mXd, mYd = M.X - mX, M.Y - mY;
local result = UDim2.new(0, mXd+32, 0, mYd+211);
Frame.Position += result;
return
elseif active == false then
print("deactivate")
save = false;
mX, mY = 0, 0;
end
end)
The active variable determines if there is input, and save is used to know if the original X and Y values are put in variables on input. All should reset when I release the mouse button I originally pressed.
All help is appreciated
From what you’ve described as the bug, and what I’m reading in your code, I assume that the problem lies in the fact that Frame.Position += result is still being ran, meaning that active is still true for whatever reason. Could it be that return statement at the end?
Additionally, it is recommended to disconnect from the .Stepped event when you’re done, to prevent memory leaks, which may be the cause of this bug.
How would I disconnect the function? For RunService.Stepped:Disconnect() it throws an error saying it is not a valid member of the event
I mean I’ve seen a solution once long ago, where I put the .Stepped() event into a variable, making :Disconnect() available on it?
local stepHandle
stepHandle = RunService.Stepped:Connect(function()
...
end)
...
stepHandle:Disconnect() -- You can also put this into the connection,
-- since we've declared the variable before assigning it.
The bug was indeed due to Frame.Position += result which I fixed.
I’ve realized there is no point in calculating the distance of two mouse position points, soI’ve changed a couple of things.
The only issue is that I can move the Frame now for 2-3 seconds, then it stops moving, even when I click again. Maybe leaving the button breaks the active value, I just don’t know.
Here’s a snippet:
local SteppedEvent
SteppedEvent = RunService.Stepped:Connect(function()
if active.Value == true then
if save == false then
local mX, mY = M.X/M.ViewSizeX, M.Y/M.ViewSizeY;
local fX, fY = Frame.Position.X.Scale,Frame.Position.Y.Scale
dX, dY = fX - mX, fY - mY; -- Save the distance for current input
save = true;
print("frame:",fX, fY, "mouse:",mX, mY, "distance:", dX, dY)
end
Frame.Position = UDim2.new(M.X/M.ViewSizeX + dX, 0, M.Y/M.ViewSizeY + dY, 0);
end
end)
active.Changed:Connect(function(value)
print("CHANGED", value)
if value == false then
dX, dY = 0, 0;
save = false;
SteppedEvent:Disconnect();
end
end)
Do the print statements still work? I also can’t figure out why this is happening, maybe try reproducing it a bunch of times to see if there’s a pattern?
I’ve reconstructed the script and it works fine without needing to disconnect the function. However, the Frame’s position doesn’t update fast enough, I mean the mouse can move away from the UI object’s area where I detect the input. I use RunService.Heartbeat instead of RunService.Stepped
I forgot to mention that you should probably use RenderStepped in this case, since you want to update UI every frame to follow the mouse. This means it should also update at higher refresh rates if the player unlocks the 60FPS limit. (I’m sure physics doesn’t update at higher than 60/30FPS)
I could somewhat fix it, move for some reason the frame slides on the Y axis whenever I move it. I’ve tried approaching different methods in attempt to fix it, but I’m not a professional and I just have no clue why it is happening. @TestyLike3