How could I go about making a click and drag box?

Basically the title, Like you would on a windows or mac computer to select multiple stuff like folders and images, here’s a picture of what I mean:
Screenshot (4205)

1 Like

this is from chatgpt btw i didnt make it lol
ai has its uses sometimes u should try it on simple stuff like this to save time

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local mouse = player:GetMouse()

local gui = script.Parent -- Reference to your ScreenGui
local selectionBox = gui.SelectionBox -- Reference to your Frame
local startPoint
local dragging = false

local function updateSelectionBox()
	if startPoint and dragging then
		local currentPoint = Vector2.new(mouse.X, mouse.Y)
		local size = currentPoint - startPoint
		selectionBox.Size = UDim2.new(0, math.abs(size.X), 0, math.abs(size.Y))
		selectionBox.Position = UDim2.new(0, math.min(startPoint.X, currentPoint.X), 0, math.min(startPoint.Y, currentPoint.Y))
	end
end

-- Mouse down to start the drag
UserInputService.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		startPoint = Vector2.new(mouse.X, mouse.Y)
		dragging = true
		selectionBox.Position = UDim2.new(0, startPoint.X, 0, startPoint.Y)
		selectionBox.Size = UDim2.new(0, 0, 0, 0)
		selectionBox.Visible = true
	end
end)

-- Mouse move to update the drag
UserInputService.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseMovement and dragging then
		updateSelectionBox()
	end
end)

-- Mouse up to finish the drag
UserInputService.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		dragging = false
		selectionBox.Visible = false

		-- Call your function to handle selecting objects within the box
		local selectionStart = selectionBox.AbsolutePosition
		local selectionEnd = selectionStart + selectionBox.AbsoluteSize

		-- Iterate over your objects to check if they are within the box bounds
		-- Example: Check objects with a Position property in world space
	end
end)

Have you tested this? The selection box frame appears to freeze when the player’s mouse goes out of the window frame.

can u show me what u mean cuz i tested it

Its hard to show really, like move your mouse to the edge and go into file explorer, properties or anywhere out of the experience window and the frame appears to freeze until the mouse re-enters the experience window/tab.

thats just roblox lol it doesnt render mouse movement outside of the game just fullscreen

Do you know how I could go about checking to see which models are inside the selection frame?

this script should work for any device with a mouse if you want it to work with mobiles you will have to check when the player is holding the screen for a period of time so that it doesn’t drag whenever the player clicks normally

change the window variable to a screen gui that have a frame with position 0,0,0,0 and size 0,0,0,0

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local window = Players.LocalPlayer.PlayerGui["Dragging Window"].Frame -- replace with your window ptototype
local mouse = Players.LocalPlayer:GetMouse()
local connection = nil -- holds the renderstepped event

UserInputService.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		window.Position = UDim2.new(0, mouse.X, 0, mouse.Y)
		connection = RunService.RenderStepped:Connect(function()
			window.Size = UDim2.fromOffset((window.Position.X.Offset - mouse.X) * -1, (window.Position.Y.Offset - mouse.Y) * -1) -- resizing the frame
		end)
		window.Visible = true
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		window.Visible = false
		window.Size = UDim2.new(0,0,0,0) -- reseting the frame to prevent visual bugs later on
		window.Position = UDim2.new(0,0,0,0)-- reseting the frame to prevent visual bugs later on
		connection:Disconnect()
	end
end)

{8A092A0E-E545-432E-B254-31DD43F460B6}

if you want to check when guiObjects are inside the selection box you can use a for loop to loop through each frame (app for example) and check if they are inside the frame

newCode {The code is a mess but it works}
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local window = Players.LocalPlayer.PlayerGui["Dragging Window"].Frame -- replace with your window ptototype
local mouse = Players.LocalPlayer:GetMouse()
local connection = nil -- holds the renderstepped event

for _,app :Frame in CollectionService:GetTagged("Apps") do
	app:SetAttribute("BackGroundColor", app.BackgroundColor3) -- storing the background color so that we can revert it back if we changed it
end

CollectionService:GetInstanceAddedSignal("Apps"):Connect(function(app :Frame)
	app:SetAttribute("BackGroundColor", app.BackgroundColor3) -- the same here too
end)
	

UserInputService.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		window.Position = UDim2.new(0, mouse.X, 0, mouse.Y)

		local lastMousePositionX = mouse.X
		local lastMousePositionY = mouse.Y
		
		connection = RunService.RenderStepped:Connect(function()
			if mouse.X == lastMousePositionX and mouse.Y == lastMousePositionY then return end -- exit the loop if the mouse position didnot change {Optimization}
			lastMousePositionX = mouse.X
			lastMousePositionY = mouse.Y
			window.Size = UDim2.fromOffset((window.Position.X.Offset - mouse.X) * -1, (window.Position.Y.Offset - mouse.Y) * -1) -- resizing the frame
			
			for _,app :Frame in CollectionService:GetTagged("Apps") do
				local isInsideBox = ( app.AbsolutePosition.X >= math.min(window.AbsolutePosition.X, window.AbsolutePosition.X + window.Size.X.Offset)
					and app.AbsolutePosition.Y >= math.min(window.AbsolutePosition.Y, window.AbsolutePosition.Y + window.Size.Y.Offset) and
					app.AbsolutePosition.X + app.AbsoluteSize.X <= math.max(window.AbsolutePosition.X, window.AbsolutePosition.X + window.Size.X.Offset) and
					app.AbsolutePosition.Y + app.AbsoluteSize.Y <= math.max(window.AbsolutePosition.Y, window.AbsolutePosition.Y + window.Size.Y.Offset) )
				-- isInside box is true if frame is inside the selection box and is false otherwise
				if isInsideBox then
					--[[
					A APP WAS ADDED INSIDE THE SELECTION BOX
					Replace With Your Logic here
					]]
					app.BackgroundColor3 = Color3.new(0.152941, 0.772549, 1) -- an example changing the app color if its inside the box
				else 
					--[[
					App Existed Out Of The Selection Box
					Replace with your logic
					]]
					app.BackgroundColor3 = app:GetAttribute("BackGroundColor")-- reverting the color change
				end
			end
		end)
		window.Visible = true
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		window.Visible = false
		for _,app :Frame in CollectionService:GetTagged("Apps") do
			app.BackgroundColor3 = app:GetAttribute("BackGroundColor")
		end
		window.Size = UDim2.new(0,0,0,0) -- reseting the frame to prevent visual bugs later on
		window.Position = UDim2.new(0,0,0,0)-- reseting the frame to prevent visual bugs later on
		connection:Disconnect()
	end
end)

the new code will loop through every instance that have the tag Apps and check if its inside or outside the selection box there are some comments in the code

{51F8A129-6D63-451D-B661-DA5165FA19B0}

2 Likes