Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to add a detectable boolean to a part?

What I am trying to do is have a SelectionBox appear around a part upon the player's mouse hovering over the part, but only CERTAIN parts in the game can be selected. The way I would think about doing this is somehow adding a boolean to the part and then having the LocalScript in the StarterGui folder detect for this boolean, but I am completely new to Lua and ROBLOX coding and there is probably a totally different way to go about with this?


LocalScript in StarterGui:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse() --Getting the player's mouse
 
local selection = Instance.new("SelectionBox", player.PlayerGui)
selection.Color = BrickColor.new("Light blue")
 
mouse.Move:connect(function() --When the mouse moves
	local target = mouse.Target
 
	if not target then
		-- nothing selected
		selection.Adornee = nil
	else
		local canSelect = target.SelectScript.canSelect
		if canSelect then
		-- when in model mode, try and select the parents first
			if target.Parent:IsA("Model") then
				selection.Adornee = target.Parent
			else
				selection.Adornee = target
			end
		else
			selection.Adornee = nil
		end
	end
end)

SelectScript in the model that can be selected:

canSelect = true

Thank you.


Working code: (!)

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local found = false
local canSelect
local colour = BrickColor.new("Light blue")

local selection = Instance.new("SelectionBox", player.PlayerGui)
selection.Color = colour

mouse.Move:connect(function()
    local target = mouse.Target
	
    if not target then
        selection.Adornee = nil --if nothing is selected
		found = false
    else
        if target.Parent:IsA("Model") and not target.Parent:IsA("Workspace") then --every parts parent is workspace, which is also a model, so thsi accounts for that
			canSelect = target.Parent:FindFirstChild("CanSelect") --looks for CanSelect in the target Parent if target is part of a model
			if canSelect then
				if not found then --if we CanSelect and we are not selecting something already
	            	selection.Adornee = target.Parent
					--Instance.new("ClickDetector", target.Parent)
					print ("Model can be selected!")
					found = true
				end
			else
				selection.Adornee = nil --if we could not find CanSelect
				found = false
			end
		else --if target is not part of a model
			canSelect = target:FindFirstChild("CanSelect") --looks for CanSelect in the target
			if canSelect then --follow the same procedure as in a model, but without referencing target Parent
				if not found then
	            	selection.Adornee = target
					print ("BasePart can be selected!")
					found = true
				end
			else
				selection.Adornee = nil
				found = false;
			end
        end
    end
end)

2 answers

✓ Accepted answer

This will not work as variables, global AND local, will only be in one script. You can instead insert a BoolValue into the model. Set the value property to true and name the value "CanSelect". Then edit the canSelect variable line to this.

local canSelect = target:FindFirstChild("CanSelect")

Also there'll be a few more changes I added to optimize the script:

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

local selection = Instance.new("SelectionBox", player.PlayerGui)
selection.Color = BrickColor.new("Light blue")

mouse.Move:connect(function()
    local target = mouse.Target
    if not target then
        selection.Adornee = nil
    else
        local canSelect = target:FindFirstChild("CanSelect")
        if canSelect then --If they can find the first child of target named "CanSelect", the script continues
            if target.Parent:IsA("Model") then
                selection.Adornee = target.Parent
            else
                selection.Adornee = target
            end
        else
            selection.Adornee = nil
        end
    end
end)

For your new problem, here's a quick fix.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local found = false

local selection = Instance.new("SelectionBox", player.PlayerGui)
selection.Color = BrickColor.new("Light blue")

mouse.Move:connect(function()
    local target = mouse.Target

    if not target then
        selection.Adornee = nil --if nothing is selected
        found = false
    else
        local canSelect = target:FindFirstChild("CanSelect")
	if target.Parent:IsA("Model") or target.Parent:IsA("Part") then --You can do both here! Just use "or"!
            canSelect = target.Parent:FindFirstChild("CanSelect")
            if canSelect then
                if not found then
                    selection.Adornee = target.Parent
                    print ("Model can be selected!")
                    found = true
                end
            else
                selection.Adornee = nil
                found = false
            end
        else
            if canSelect then
                if not found then
                    selection.Adornee = target
                    print ("BasePart can be selected!")
                    found = true
                end
            else
                selection.Adornee = nil
                found = false
            end
        end
    end
end)

Please hit the accept button if it worked! If not, leave a comment, don't be afraid!

8 comments

0

Alternatively, you might want to set the "Locked" property of the part to false and check for the value of that property.

0

Thank you very much for your reply! I have since learned about other objects like IntValue and ObjectValue that should make coding in the future so much easier. I also appreciate you taking the time to improve the GUI script, but I have run into some problems. This code does not work with models as the "target" variable targets individual parts, and "canSelect" has to been set to find the child of

0

the target, when in a model the CanSelect BoolValue will only be found in the Parent of the target. So this works fine with BaseParts, but for some reason when the mouse goes over a BasePart with CanSelect, a SelectionBox appears around the entire map and not just that target?

0

Hm, so have you got it covered or should I help you out?

0

See my answer below for the current code, I still can't figure out why parts that do not belong to a model can not be highlighted, I'd really appreciate any help

0

Edited. Line 16 of the last code block.

0

Sorry, still doesn't work. I'll leave an accept on your answer as a thank you for the help you've already given, don't worry yourself over fixing this small thing

0

I found the fix! I think RBX.Lua treats the Workspace as a Model type object. Therefore EVERY part in the game has a parent that is a model, and my code would never reach the "else" statement that goes onto check individual parts. See code above

To follow up on my reply, this is the current code. Selecting models works perfectly, but it does not seem to work on anything that is not a model.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local found = false

local selection = Instance.new("SelectionBox", player.PlayerGui)
selection.Color = BrickColor.new("Light blue")

mouse.Move:connect(function()
    local target = mouse.Target
	
    if not target then
        selection.Adornee = nil --if nothing is selected
		found = false
    else
		local canSelect = target:FindFirstChild("CanSelect") --looks for CanSelect in the target
        if target.Parent:IsA("Model") then
			canSelect = target.Parent:FindFirstChild("CanSelect") --looks for CanSelect in the target Parent if target is part of a model
			if canSelect then
				if not found then --if we CanSelect and we are not selecting something already
	            	selection.Adornee = target.Parent
					print ("Model can be selected!")
					found = true
				end
			else
				selection.Adornee = nil --if we could not find CanSelect
				found = false
			end
		else --if target is not part of a model
			if canSelect then --follow the same procedure as in a model, but without referencing target Parent
				if not found then
	            	selection.Adornee = target
					print ("BasePart can be selected!")
					found = true
				end
			else
				selection.Adornee = nil
				found = false;
			end
        end
    end
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.