Apologies if the title does not explain much. I’m making a destroy system that requires you to select a part that you’ve built. I need it so a selection box appears at selecting specific parts that you’ve built. I’ve tried some code but it doesn’t seem to work. I’d be really pleased if I’d gather some help.
Heres some articles that should help!
Mouse | Roblox Creator Documentation (mouse.Hit) is what you need to use ( i believe )
Just create a selection box in a localscript on the object that was hit ( mouse.Hit ).
The knowledge you’ll need for this may include the following:
- UserInputService | Roblox Creator Documentation
Mouse
- Highlighting Objects | Roblox Creator Documentation
- Tables | Roblox Creator Documentation
Basically what you want to do is have a table like so:
local Selected = {}
And then whenever the player selects a part (using Mouse | Roblox Creator Documentation if you want a quick and easy way and UserInputService
if you want a more universal method) you can add it to the table. This would look something like this:
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Selected = {}
Mouse.Button1Down:Connect(function()
local Target = Mouse.Target -- The part the mouse may be hovering over
if Target and Target.Parent then
Selected = {Target}
else -- This else statement deselects all parts if we aren't clicking on any parts
Selected = {}
end
end)
However, what if you wish to select multiple parts? We need a way to easily do this if it is a feature you want. We can use the leftshift key to toggle this behavior. We will be using UserInputService | Roblox Creator Documentation to detect if this key is being pressed down. If it is then we will instead add the part to the selection rather than resetting it. This may look like this:
local UserInputService = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Selected = {}
Mouse.Button1Down:Connect(function()
local Target = Mouse.Target
local SelectMultiple = UserInputService:IsKeyDown(Enum.Keycode.LeftShift) -- This will detect if we are holding down the leftshift
local check = table.find(Selected, Target) -- This checks if the part is already in the table
if Target and Target.Parent then
if SelectMultiple then
if check then -- If it is already selected then we remove it from the table
table.remove(Selected, check) -- removes an already selected item
else
table.insert(Selected, Target) -- adds the part to the table
end
else
Selected = {Target}
end
elseif not SelectMultiple then -- We have changed this so it doesn't deselect all the parts if we are trying to select multiple parts and did not select one
Selected = {}
end
end)
Great! Our code should be working now. However, there is one last thing that needs to be done. We need a way to visualize the parts selected to let the user know which ones are selected. Otherwise they may lose track of the parts they selected! We will do this using SelectionBox | Roblox Creator Documentation. If you want to add a system that also highlights the part the mouse is hovering over you can use Mouse | Roblox Creator Documentation, although you will have to make this on your own. Anyways, to do this we can use a function. This will help you later on if you need to use selection boxes in a different part of your code. Also, if we want to reduce the potential lag creating by instancing then we should keep track of the selection boxes not in use so we can use them later to prevent creating new ones. Here are two functions you can use to control what parts are highlighted:
local Boxes = {
InUse = {},
Cache = {},
}
local function HightlightPart(part)
local box = table.remove(Boxes.Cache, 1) -- retrieves an unused selection box if there is one
if not box then -- creates a box if there wasn't one in the cache
box = Instance.new("SelectionBox")
box.LineThickness = 0.05
box.Adornee = part
box.Parent = workspace
end
box.Adornee = part
table.insert(Boxes.InUse, box)
end
local function UnhightlightPart(part)
local position, box
for i,selection in pairs(Boxes.InUse) do
if selection.Adornee == part then
position = i
box = selection
end
end
if box then
box.Adornee = nil
table.insert(Boxes.Cache, table.remove(Boxes.InUse, position))
end
end
P.S. - This code is untested and may not work. However, you should be able to get a general idea of what needs to happen to make a selection system
P.P.S. - If you want to use UserInputService
instead of the Mouse
object (I strongly recommend this) you can use UserInputService | Roblox Creator Documentation, UserInputService | Roblox Creator Documentation, and/or UserInputService | Roblox Creator Documentation to get the users mouse position. You will have to convert the Vector2
into a Vector3
though.
So shall I insert code to check which part you’ve selected?
I edited my original post. Also, what do you mean by this?
Do you mean should you use UserInputService
in place of the Mouse
object? If so then that’s up to you. Personally I’ve never cared enough to figure out how to convert a Vector2
into a Vector3
, mostly because I just code for fun. I’ll probably learn one of these days though. I would encourage you to use UserInputService
instead of the Mouse
object though.
If you mean add a way to visualize what parts are selected then sure. You can add your own code or use the two functions I provided in my edited post.
EDIT: I just looked at the Selection Boxes
link I provided to you in my post. You should check it out, as it apparently had a code sample for selecting parts as well.
Alright, I’ve tested my code and edited it to survive the infant mortality rate that code suffers from. I’ll also edit my original post so it doesn’t error if anyone in the future stumbles across this post and wants to use the code. Anyways, here’s the final script:
local UserInputService = game:GetService("UserInputService")
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Selected = {}
local Boxes = {
InUse = {},
Cache = {},
}
local function HightlightPart(part)
local box = table.remove(Boxes.Cache, 1) -- retrieves an unused selection box if there is one
if not box then -- creates a box if there wasn't one in the cache
box = Instance.new("SelectionBox")
box.LineThickness = 0.05
box.Adornee = part
box.Parent = workspace
end
box.Adornee = part
table.insert(Boxes.InUse, box)
end
local function UnhightlightPart(part)
local position, box
for i,selection in pairs(Boxes.InUse) do
if selection.Adornee == part then
position = i
box = selection
end
end
if box then
box.Adornee = nil
table.insert(Boxes.Cache, table.remove(Boxes.InUse, position))
end
end
Mouse.Button1Down:Connect(function()
local Target = Mouse.Target
local SelectMultiple = UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) -- This will detect if we are holding down the leftshift
local check = table.find(Selected, Target) -- This checks if the part is already in the table
if Target and Target.Parent then
if SelectMultiple then
if check then -- If it is already selected then we remove it from the table
UnhightlightPart(Target)
table.remove(Selected, check) -- removes an already selected item
else
HightlightPart(Target)
table.insert(Selected, Target) -- adds the part to the table
end
elseif not check then -- If it is not selected then we select it
HightlightPart(Target)
table.insert(Selected, Target) -- adds the part to the table
end
elseif not SelectMultiple then -- We have changed this so it doesn't deselect all the parts if we are trying to select multiple parts and did not select one
for _,part in pairs(Selected) do
UnhightlightPart(part)
end
table.clear(Selected)
end
end)
You don’t even need table for that just store it in variable
local Selected
local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
if Selected ~= Mouse.Target and Mouse.Target ~= nil and Mouse.Target:IsA("BasePart") then
Selected = Mouse.Target
end
Only case I think you will ever need table for something like this is finding nearby parts but other than that well explained!
I know, but this was meant to be more of a tutorial that steadily introduced each part. I used tables to help to allow for more customization. If they don’t need tables then they will still grasp the basic concepts and be able to edit it so that it only used one.
It’s… a little complex but I’ll try cope
Can you maybe… compress the code or explain it more thourghly
This code is perfect for me! Except, one thing, my fps drops to 30 when I select multiple new parts in succession. I suspect it has to do something with the Instance.new("SelectionBox")
, because the effect goes away once I have quite a few boxes stored up in my cache. Thanks!