so im trying to make a inventory/hotbar system where ur able to drag stuff from your inventory, then put them on ur hotbar and vise versa, also able to switch arround the items in the players hotbar. i have an iossue with the dragging system, first issue is that whenever i try to drag the ui the ui appears further away from my mouse:
local runservice = game:GetService("RunService")
local plr = game:GetService("Players").LocalPlayer
local inventoryGui = plr.PlayerGui.Inventory
local scrollingframe = inventoryGui.Inventory.ScrollingFrame
local hotbarframe = inventoryGui.HotBarFrame
local Drag = script.Parent
gsCoreGui = game:GetService("CoreGui")
gsTween = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
function IsOverlapping(f1,f2)
local f1pos,f2pos,f1size,f2size = f1.AbsolutePosition,f2.AbsolutePosition,f1.AbsoluteSize,f2.AbsoluteSize
local xoverlap = (f1pos.x <= f2pos.x and f2pos.x < f1pos.x + f1size.x)
local yoverlap = (f1pos.y <= f2pos.y and f2pos.y < f1pos.y - f1size.y)
return xoverlap or yoverlap
end
local dragging
local dragInput
local dragStart
local startPos
local function update(input)
local delta = input.Position - dragStart
local dragTime = 0.04
local SmoothDrag = {}
SmoothDrag.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
local dragSmoothFunction = gsTween:Create(Drag, TweenInfo.new(dragTime, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), SmoothDrag)
dragSmoothFunction:Play()
end
Drag.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
Drag.Parent = inventoryGui
dragging = true
dragStart = input.Position
startPos = Drag.Position
input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
if IsOverlapping(Drag, scrollingframe) then
Drag.Parent = scrollingframe
else
for i,v in hotbarframe:GetChildren() do
if IsOverlapping(Drag,v) then
Drag.Position = v.Position
return
end
end
Drag.Parent = scrollingframe
end
end
end)
end
end)
Drag.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging and Drag.Size then
update(input)
end
end)
it’s likely because Drag.Position uses UDim2, which doesn’t directly map to the mouse’s AbsolutePosition. Instead, try setting Drag.Position relative to the parent’s AbsoluteSize:
local function update(input)
local delta = input.Position - dragStart
Drag.Position = UDim2.new(0, delta.X + startPos.X.Offset, 0, delta.Y + startPos.Y.Offset)
end
UIGridLayouts are very strict with position and size, it wont let you move an object etc…
My idea → Clone the UI you are trying to drag → .Visible = false the one in the UIGridLayout Frame
When the player drags out, then you can :Destroy the one in the UIGridLayout Frame, if they drag back into the inventory just set .Visible back to true
Edit: you probably dont need to clone actually, just reparent it to a corresponding ScreenGUI
Quite an old thread, but something you could try doing is have a UIListLayout of invisible UI with UIDragDetector-equipped UI as a children of the layout-controlled UI.
That way, you could visibly drag UI, and on release you could reset the position, and have logic act on the layout-controlled UI (The parent UI) and change around the layout ordering via scripting.