im trying to make a selection box that drags the selected GUIs around the screen.
but the problem is the GUIs thats being selected wont maintain the selection box’s position+ the distance between the guis and th selection box postiions. Is there something im doing wrong?
heres the touch script under the selection box
local RunService = game:GetService("RunService")
local Collectionservice = game:GetService("CollectionService")
local group = {}
function areFramesOverlapping(Frame1,Frame2)
-- X axis overlap detection
local F1posX,F2posX = Frame1.AbsolutePosition.X,Frame2.AbsolutePosition.X
local F1sizeX,F2sizeX = Frame1.AbsoluteSize.X,Frame2.AbsoluteSize.X
local Xdistance = math.abs(F1posX-F2posX) -- distance (in px) between frames
local minXdistance = math.abs(F1sizeX+F2sizeX/2)-- min distance w/o overlap
-- Y axis overlap detection
local F1posY,F2posY = Frame1.AbsolutePosition.Y,Frame2.AbsolutePosition.Y
local F1sizeY,F2sizeY = Frame1.AbsoluteSize.Y,Frame2.AbsoluteSize.Y
local Ydistance = math.abs(F1posY-F2posY) -- distance (in px) between frames
local minYdistance = math.abs(F1sizeY+F2sizeY/2)-- min distance w/o overlap
if Ydistance < minYdistance and Xdistance < minXdistance then return true end -- OVERLAP!!
return false -- no overlap detected
end
function OnTouch(b)
if b == nil then return end
local a = script.Parent
local debounce = false
if areFramesOverlapping(a,b) == true then
b.UIStroke.Enabled = true
table.insert(group,b)
b:setAttribute("distance",b.AbsolutePosition.X-a.AbsolutePosition.X)
repeat task.wait()
until areFramesOverlapping(a,b) == false
b.UIStroke.Enabled = false
b:setAttribute("distance",0)
group[b] = nil
end
end
local guiInset = game:GetService("GuiService"):GetGuiInset()
local function isInScreen(gui)
local pos = gui.AbsolutePosition + guiInset
return pos.Y + gui.AbsoluteSize.Y <= (game.Workspace.CurrentCamera.ViewportSize.Y * 2) and pos.Y >= 0
end
game.ReplicatedStorage.Functions.GetSelected.OnInvoke = function()
return group
end
game.ReplicatedStorage.Events.Deselect.Event:Connect(function()
table.clear(group)
end)
script.Parent.Destroying:Connect(function()
for i, v in pairs(group) do
v.UIStroke.Enabled = false
group[v] = nil
end
end)
RunService.Heartbeat:Connect(function()
for i, b in pairs(Collectionservice:GetTagged("regions")) do
isInScreen(b)
if isInScreen(b) == true then
if script.Parent.BackgroundColor3 == Color3.new(0.333333, 0.333333, 1) then
coroutine.wrap(OnTouch)(b)
end
end
end
end)
heres the drag script in the selection box
local UserInputService = game:GetService("UserInputService")
local gui = script.Parent
local dragging
local dragInput
local dragStart
local startPos
local tagsystem = game:GetService("CollectionService")
local function filter(number,increment)
number = math.floor(number)
number = number-(number%increment)
return number
end
local Increment = 25
local function update(input)
local delta = input.Position - dragStart
gui.Position = UDim2.new(gui.Position.X.Scale,startPos.X.Offset + delta.X ,gui.Position.Y.Scale,gui.Position.Y.Offset)
end
local debounce = false
gui.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
if debounce == false then
debounce = true
dragging = true
dragStart = input.Position
startPos = gui.Position
input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
dragging = false
wait()
debounce = false
end
end)
end
end
end)
gui.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
local pos
UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging then
update(input)
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
local delta = input.Position - dragStart
note.Position = UDim2.new(0,gui.AbsolutePosition.X+note:GetAttribute("distance"),0,0)
end
end
end)
and heres the script that creates the selection box
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local UIS = game:GetService("UserInputService")
local imageframe = script.Parent.Octaves
local GuiCollisionService = require(game:GetService("ReplicatedStorage").GuiCollisionService)
local function Hovering(Frame)
local MousePos = game:GetService("UserInputService"):GetMouseLocation() - game:GetService("GuiService"):GetGuiInset()
local Guis = player:WaitForChild("PlayerGui"):GetGuiObjectsAtPosition(MousePos.X, MousePos.Y)
for _, Gui in Guis do
if Gui == Frame then
return true
end
end
return false
end
UIS.InputBegan:connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
local oldframe = script.Parent:FindFirstChild("Select")
if oldframe == nil then
local frame = game.ReplicatedStorage.Assets.Select:Clone()
frame.Parent = script.Parent
frame.Name = ("Select")
frame.BackgroundTransparency = 0.8
frame.BackgroundColor3 = Color3.new(0.333333, 0.333333, 1)
local uistroke = Instance.new("UIStroke")
uistroke.Color = Color3.new(0.333333, 0.333333, 0.498039)
uistroke.Parent = frame
frame.Position = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
repeat
task.wait()
frame.Size = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
until input.UserInputState == Enum.UserInputState.End
else
if not Hovering(oldframe) then
local group = game.ReplicatedStorage.Functions.GetSelected:Invoke()
for i, region in pairs(group) do
region.UIStroke.Enabled = false
end
oldframe:Destroy()
local frame = game.ReplicatedStorage.Assets.Select:Clone()
frame.Parent = script.Parent
frame.Name = ("Select")
frame.BackgroundTransparency = 0.8
frame.BackgroundColor3 = Color3.new(0.333333, 0.333333, 1)
local uistroke = Instance.new("UIStroke")
uistroke.Parent = frame
uistroke.Color = Color3.new(0.333333, 0.333333, 0.498039)
frame.Position = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
repeat
task.wait()
frame.Size = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
until input.UserInputState == Enum.UserInputState.End
end
end
end
end)
UIS.InputEnded:connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
wait()
local frame = script.Parent:FindFirstChild("Select")
if frame ~= nil then
local selected = script.Parent.Select
selected.BackgroundColor3 = Color3.new(0.333333, 0.333333, 0.498039)
wait(0.1)
local nearestPos = 100000
local furthestPos = 0
local LowestPos = 0
local HighestPos = 10000
local nearest = nil
local furthest = nil
local highest = nil
local distance = nil
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then
selected:Destroy()
return
end
local distance = note.AbsolutePosition.X
if distance < nearestPos then
nearestPos = distance
nearest = note
selected.Position = UDim2.new(UDim.new(0,nearest.Position.X.Offset),selected.Position.Y)
end
end
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then return end
local distance = note.AbsolutePosition.X+note.AbsoluteSize.X
if distance > furthestPos then
furthestPos = distance
furthest = note
selected.Size = UDim2.new(UDim.new(0,furthest.Position.X.Offset-nearest.Position.X.Offset+furthest.Size.X.Offset),selected.Size.Y)
end
end
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then return end
local distance = note.AbsolutePosition.Y
if distance < HighestPos then
HighestPos = distance
highest = note
selected.Position = UDim2.new(selected.Position.X,UDim.new(0,highest.AbsolutePosition.Y-highest.Parent.Parent.Parent.AbsolutePosition.Y))
end
end
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then return end
distance = note.AbsolutePosition.Y
if distance > LowestPos then
LowestPos = distance
local lowest = note
local desiredAbsolutePosition = lowest.AbsolutePosition
local relativePosition = desiredAbsolutePosition - selected.Parent.AbsolutePosition
selected.Size = UDim2.new(selected.Size.X,UDim.new(0,lowest.AbsolutePosition.Y-highest.AbsolutePosition.Y+lowest.AbsoluteSize.Y))
end
end
else
return
end
end
end)
imageframe.MouseLeave:Connect(function()
wait()
local frame = script.Parent:FindFirstChild("Select")
if frame ~= nil then
local selected = script.Parent.Select
selected.BackgroundColor3 = Color3.new(0.333333, 0.333333, 0.498039)
wait(0.1)
local nearestPos = 100000
local furthestPos = 0
local LowestPos = 0
local HighestPos = 10000
local nearest = nil
local furthest = nil
local highest = nil
local distance = nil
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then
selected:Destroy()
return
end
local distance = note.AbsolutePosition.X
if distance < nearestPos then
nearestPos = distance
nearest = note
selected.Position = UDim2.new(UDim.new(0,nearest.Position.X.Offset),selected.Position.Y)
end
end
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then return end
local distance = note.AbsolutePosition.X+note.AbsoluteSize.X
if distance > furthestPos then
furthestPos = distance
furthest = note
selected.Size = UDim2.new(UDim.new(0,furthest.Position.X.Offset-nearest.Position.X.Offset+furthest.Size.X.Offset),selected.Size.Y)
end
end
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then return end
local distance = note.AbsolutePosition.Y
if distance < HighestPos then
HighestPos = distance
highest = note
selected.Position = UDim2.new(selected.Position.X,UDim.new(0,highest.AbsolutePosition.Y-highest.Parent.Parent.Parent.AbsolutePosition.Y))
end
end
for i, note in pairs(game.ReplicatedStorage.Functions.GetSelected:Invoke()) do
if note == nil then return end
distance = note.AbsolutePosition.Y
if distance > LowestPos then
LowestPos = distance
local lowest = note
local desiredAbsolutePosition = lowest.AbsolutePosition
local relativePosition = desiredAbsolutePosition - selected.Parent.AbsolutePosition
selected.Size = UDim2.new(selected.Size.X,UDim.new(0,lowest.AbsolutePosition.Y-highest.AbsolutePosition.Y+lowest.AbsoluteSize.Y))
end
end
else
return
end
end)