You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I want to be able to snap frames into each other after dragging and releasing them. Like a drag and drop inventory system.
What is the issue? Include screenshots / videos if possible!
I can’t figure out how to determine which frame the draggable frame should snap to.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I currently have a draggable frame. I have looked all over the internet and cannot find any help to describe the process of determing which frame to snap to.
Here is my current code for a draggable frame
local UIS = game:GetService("UserInputService")
local frame = script.Parent
local Dragtoggle = nil
local dragSpeed = 0.01
local dragstart = nil
local startPOS = nil
local function updateInput(input)
local delta = input.Position - dragstart
local pos = UDim2.new(startPOS.X.Scale, startPOS.X.Offset + delta.X,
startPOS.Y.Scale, startPOS.Y.Offset + delta.Y)
game:GetService("TweenService"):Create(frame, TweenInfo.new(dragSpeed), {Position = pos}):Play()
end
frame.InputBegan:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.MouseButton1) then
Dragtoggle = true
dragstart = input.Position
input.Changed:Connect(function()
startPOS = frame.Position
if input.UserInputState == Enum.UserInputState.End then
Dragtoggle = false
end
end)
end
end)
UIS.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement then
if Dragtoggle then
updateInput(input)
end
end
end)
I want to be more clear on what I’m trying to achieve. In an inventory system with multiple frames, I want to be able to drag an item (frame) within the tiles and drop it with the item going to the nearest frame. I cannot figure out how to determine which frame the item is closest too. From there I have an idea on how to snap the two elements. However, all help is appreciated.
Edit: I just read your explanation of what you mean by “snapping”.
You could loop through all the item slots and find the distance between the dragged frame and the slot, and then pick the one with the minimum distance. (math.min would be useful to do this easily)
local draggable = script.Parent.draggable
local Frame1 = script.Parent.slot1
local Frame2 = script.Parent.slot2
local Frame3 = script.Parent.slot3
function CalculateDistance1()
local distance = draggable.AbsolutePosition - Frame1.AbsolutePosition
return distance
end
print(CalculateDistance1())
function CalculateDistance2()
local distance = draggable.AbsolutePosition - Frame2.AbsolutePosition
return distance
end
print(CalculateDistance2())
function CalculateDistance3()
local distance = draggable.AbsolutePosition - Frame3.AbsolutePosition
return distance
end
print(CalculateDistance3())
math.min(CalculateDistance1(), CalculateDistance2(), CalculateDistance3())
however I’m wondering how to get a singular distance value from the absolutePosition. In order for the Math.min to work
Thanks so much! I don’t know why I didn’t think of that. I’m going to attach my code incase anyone could want it in the future.
local UIS = game:GetService("UserInputService")
local frame = script.Parent
local Dragtoggle = nil
local dragSpeed = 0
local dragstart = nil
local startPOS = nil
local function updateInput(input)
local delta = input.Position - dragstart
local pos = UDim2.new(startPOS.X.Scale, startPOS.X.Offset + delta.X,
startPOS.Y.Scale, startPOS.Y.Offset + delta.Y)
game:GetService("TweenService"):Create(frame, TweenInfo.new(dragSpeed), {Position = pos}):Play()
end
--------------------------------------------------------------------
frame.InputBegan:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.MouseButton1) then
Dragtoggle = true
dragstart = input.Position
end
end)
frame.InputEnded:Connect(function(input)
startPOS = frame.Position
-- input ended. calculates distance
Dragtoggle = false
local Frame1 = script.Parent.Parent.slot1
local Frame2 = script.Parent.Parent.slot2
local Frame3 = script.Parent.Parent.slot3
local function CalculateDistance1()
local xDifference = frame.AbsolutePosition.X - Frame1.AbsolutePosition.X
local yDifference = frame.AbsolutePosition.Y - Frame1.AbsolutePosition.Y
local distance = math.sqrt(xDifference^2 + yDifference^2)
return distance
end
local function CalculateDistance2()
local xDifference = frame.AbsolutePosition.X - Frame2.AbsolutePosition.X
local yDifference = frame.AbsolutePosition.Y - Frame2.AbsolutePosition.Y
local distance = math.sqrt(xDifference^2 + yDifference^2)
return distance
end
local function CalculateDistance3()
local xDifference = frame.AbsolutePosition.X - Frame3.AbsolutePosition.X
local yDifference = frame.AbsolutePosition.Y - Frame3.AbsolutePosition.Y
local distance = math.sqrt(xDifference^2 + yDifference^2)
return distance
end
local lowestvalue = math.min(CalculateDistance1(), CalculateDistance2(), CalculateDistance3())
if lowestvalue == CalculateDistance1() then
frame.Position = Frame1.Position
end
if lowestvalue == CalculateDistance2() then
frame.Position = Frame2.Position
end
if lowestvalue == CalculateDistance3() then
frame.Position = Frame3.Position
end
end)
UIS.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement then
if Dragtoggle then
updateInput(input)
end
end
end)