Selection system

Selection system :

1. The settings
  1. Create a ScreenGui in StarterGui and add a frame to it, in the frame add a UIStroke, the frame will represent the area of selection :
  2. Check the IgnoreGuiInset property of your ScreenGui and set the transparency of your frame to 1, after that you can change the thickness of your UIStroke to 2 and the color to [255, 255, 255] :
    image image
  3. Create a LocalScript in your frame and you’re done for the settings :
  4. Create a SelectionBox in every selectable parts and set the adornee to the part you want to be highlighted, the color to [255, 255, 255] the line thickness to 0.1 and uncheck visible :
2. The script
  1. Remove the print("Hello World !") and add the variables that we will need :
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local Camera = workspace.Camera
local Frame = script.Parent
local Origin =, 0) --Where your mouse started to held
local SelectedParts = {} --The table that will store as a dictionary every selected parts
local LastSelectedParts = {} --The table that will store the last selected parts if control is down
  1. Create the function that will set the point Origin :
local function SetOrigin()
	Origin = UserInputService:GetMouseLocation() --Origin is now equal to the mouse position
  1. Create the function that will return a table of every selected parts :
local function GetSelectedParts()
	local Parts = table.clone(LastSelectedParts)
	local Target = Mouse.Target
	Parts[Target] = Target:FindFirstChildOfClass("SelectionBox") and LastSelectedParts[Target] == nil and Target or nil
	for v, Part in pairs(workspace:GetDescendants()) do
		if Part:IsA("BasePart") then
			local MousePosition = UserInputService:GetMouseLocation()
			local Position, Visible = Camera:WorldToViewportPoint(Part.Position)
			if Part:FindFirstChildOfClass("SelectionBox") and Visible and math.sign(Position.X - MousePosition.X) * math.sign(Position.X - Origin.X) + math.sign(Position.Y - MousePosition.Y) * math.sign(Position.Y - Origin.Y) < 0 then
				if LastSelectedParts[Part] then
					Parts[Part] = nil
					Parts[Part] = Part
	return Parts
  1. Create a function that will update your frame size and position, that will show you selected parts and that will set LastSelectedParts :
local function Update()
	if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
		local Difference = UserInputService:GetMouseLocation() - Origin
		local X, Y = math.abs(Difference.X), math.abs(Difference.Y)
		Frame.Size = UDim2.fromOffset(X, Y)
		Frame.Position = UDim2.fromOffset(Difference.X > 0 and Origin.X or Origin.X - X, Difference.Y > 0 and Origin.Y or Origin.Y - Y)
		Frame.Visible = Difference.Magnitude > 0
		for v, Part in pairs(SelectedParts) do
			Part.SelectionBox.Visible = false
		SelectedParts = GetSelectedParts() --function previously created
		for v, Part in pairs(SelectedParts) do
			Part.SelectionBox.Visible = true
		Frame.Visible = false
		if UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
			LastSelectedParts = SelectedParts
			LastSelectedParts = {}
  1. Now we can connect our functions to events :
3. The result

Don’t forget to tell me if there’s something wrong or if something is bad explained, I hope that was helpful and have a nice day !!!


For some reasons, I can’t play the Video. Don’t know whether it’s just me or it’s really broken for everyone. New version of video got uploaded.

I feel that more detailed explanations for the Settings section could be done. Maybe specify how exactly it will help with the system, instead of just telling the reader what to create.

For the Script section, maybe specify the functions of slightly longer lines. Newer developers might now understand what this means:

A little write-up at the start of this tutorial on what exactly this will be making, how it works, and some examples of it being in games, would also be useful.

Finally, this topic should be categorised under #resources:community-tutorials instead of #resources:community-resources !


That’s great!

Also, link version of the video in case someone doesn’t wants to download the file: Video here

1 Like

This version is only for feedback I think that after receiving enought feedback I will make a better tutorial or ressources !
I have just a little question, cause of course a beginner will not understand but every programmer can easily understand what this script can do so basicaly should I keep this topic under ressources and so maybe make kind of a module or should I make a very detailled explaination of all !
I feel like the first option is the best since it’s very hard to make it understandable to beginners !

This is still a tutorial overall. You are still teaching the reader how to create their own system. Things like Plugins are more suiting to be under Community Resources, as they are a system pre-made and ready for Developers to use.

1 Like

I cannot make this as a plugin of course :joy:
So you still think that I need to move this topic to #resources:community-tutorials ?

Yes, pretty much. This means having to do some editing to your current post as well.

1 Like

Ok !
I will move on so !
Thanks you very much for your feedback !

1 Like

The video is now readable directly from the devforum !


Finally I will make it as a plugin :rofl:
Here a little sneak peek of how it will looks :
I hope you’ll like it !