How to create a Selection Box

Hello, I am currently working on a large project which is only in its conception. And I am stuck on one point, how to make a selection box such as the one found on Roblox studio.

I thought about using the ray cast, but scanning a whole rectangle might not be very efficient, do you have any solution?

2 Likes

The attached image is the roblox selection box, an example of what I want to do.

There is a Instance called SelectionBox, maybe this could help you understand it.

That’s not exactly what I’m talking about, I’m talking about the square drawn with the mouse. :sweat_smile:

This should work perfectly. Once you open this you put it in starter gui then you can start to scale the frame inside of it, pretty sure this is what you where looking for.

HoverUI.rbxm (2.2 KB)

You’re almost there, which interests me being the next step. How to know which parts are in the frame. :joy:

Wdym? You can scale the first frame inside the screengui, its called “1”, Once you scale it, it should be acting correctly and working perfectly.

Are you doing it on purpose? You just got the roblox interface, what interests me is not how to draw a frame, I think I’m big enough to do it on my own but how to code a system like this.

Oh… Well you can use UserInputService and check when a input begans and if its Enum.UserInputType.MouseButton1 you want to get the mouse position and update the frame each RenderStepped then when it input ends destroy the ui or disable it.

I want to do something like this.

Salutations Zayer

I can’t seem to understand your question very well but, you could do something similar to this :

  1. Determine the world positions of each corners, using :ScreenPointToRay()

  2. Iterate through the instances, to significantly reduce the amount of parts to loop, you could put the selectable parts in a certain folder

  3. Check whenever the instance is within the rectangle bounds by comparing their positions or using :ToObjectSpace(), if so you could insert the part into an array

  4. Speaking performance-wise, you can still improve a lot and this isn’t any case the optimized way.

I can’t provide any code sample since I’m quite busy, but that’s pretty much how you could conceive that.

Hey, thank you, this is exactly what I wanted, I will experiment a little in order to have a good result, really thank you :D.

1 Like

I think I have the perfect solution for you!

local uis = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera

local frame = script.Parent.Frame
frame.Size = UDim2.fromScale(0, 0)
frame.BackgroundTransparency = 0.5 -- Optional

local button1Down = false

local startPos = nil
local endPos = nil

mouse.Button1Down:Connect(function()
	button1Down = true
	startPos = Vector2.new(mouse.X, mouse.Y)
	frame.Position = UDim2.fromOffset(mouse.X, mouse.Y)
	frame.Size = UDim2.fromScale(0, 0)
	
	while task.wait() and button1Down do
		endPos = Vector2.new(mouse.X, mouse.Y)
		frame.Size = UDim2.fromOffset(mouse.X - startPos.X, mouse.Y - startPos.Y)
	end
	
	local top = endPos.Y
	local bottom = startPos.Y
	if startPos.Y < endPos.Y then
		top = startPos.Y
		bottom = endPos.Y
	end
	
	local left = endPos.X
	local right = startPos.X
	if startPos.X < endPos.X then
		left = startPos.X
		right = endPos.X
	end
	
	local selectedParts = {}
	
	for i, v in workspace:GetChildren() do
		local s, e = pcall(function()
			local vector, onScreen = camera:WorldToScreenPoint(v.Position)
			
			if (vector.X > left) and (vector.X < right) and (vector.Y < bottom) and (vector.Y > top) then
				table.insert(selectedParts, v)
			end
		end)
	end
end)

mouse.Button1Up:Connect(function()
	button1Down = false
end)

imagem_2024-04-14_180121500