I have a script that counts the amount a red and blue parts in the map, but it gets very laggy when there are a lot of parts.
Script:
local RS = game:GetService("RunService")
local RedParts
local BlueParts
RS.Heartbeat:Connect(function()
RedParts = 0
BlueParts = 0
for i, Part in pairs(workspace.Map:GetDescendants()) do
if not Part:IsA("BasePart") then continue end
if Part.BrickColor == BrickColor.new("Really red") then
RedParts += 1
elseif Part.BrickColor == BrickColor.new("Really blue") then
BlueParts += 1
end
end
script.Parent.RedNumber.Text = tostring(RedParts)
script.Parent.BlueNumber.Text = tostring(BlueParts)
end)
Also, this script is enabled and disabled from another script.
Run it once first to get the initial count, then ideally you would update it from whatever changes colors or adds/removes them to adjust the count so you aren’t looping through everything in heartbeat.
local RS = game:GetService("RunService")
local RedParts
local BlueParts
local D = workspace.Map:GetDescendants()
RS.Heartbeat:Connect(function()
RedParts = 0
BlueParts = 0
for i, Part in pairs(D) do
if not Part:IsA("BasePart") then continue end
if Part.BrickColor == BrickColor.new("Really red") then
RedParts += 1
elseif Part.BrickColor == BrickColor.new("Really blue") then
BlueParts += 1
end
end
script.Parent.RedNumber.Text = tostring(RedParts)
script.Parent.BlueNumber.Text = tostring(BlueParts)
end)
local Frame = script.Parent
local RedParts = 0
local BlueParts = 0
for _, Part in ipairs(workspace.Map:GetDescendants()) do
if Part:IsA("BasePart") then
if Part.BrickColor == "Really red" then
RedParts += 1
elseif Part.BrickColor == "Really blue" then
BlueParts += 1
end
end
end
Frame.RedNumber.Text = tostring(RedParts)
Frame.BlueNumber.Text = tostring(BlueParts)
for _, Part in ipairs(workspace.Map:GetDescendants()) do
if Part:IsA("BasePart") then
Part:GetPropertyChangedSignal("BrickColor"):Connect(function()
if Part.BrickColor == BrickColor.new("Really red") then
RedParts += 1
Frame.RedNumber.Text = tostring(RedParts)
elseif Part.BrickColor == BrickColor.new("Really blue") then
BlueParts += 1
Frame.BlueNumber.Text = tostring(BlueParts)
end
end)
end
end
You can make whatever changes the parts also parent them to folders named after their color and just change the textbox whenever a child is added/removed from those folders.
Another solution would be to make an intValue for the different colors and have whatever changes colors add/subtract from that value and update the guis whenever that intValue changes.
local Frame = script.Parent
local RedParts = 0
local BlueParts = 0
for _, Part in ipairs(workspace.Map:GetDescendants()) do
if Part:IsA("BasePart") then
local OldColor = Part.BrickColor
Part:GetPropertyChangedSignal("BrickColor"):Connect(function()
if Part.BrickColor == BrickColor.new("Really red") then
if OldColor == BrickColor.new("Really blue") then
BlueParts -= 1
Frame.BlueNumber.Text = tostring(BlueParts)
end
OldColor = Part.BrickColor
RedParts += 1
Frame.RedNumber.Text = tostring(RedParts)
elseif Part.BrickColor == BrickColor.new("Really blue") then
if OldColor == BrickColor.new("Really red") then
RedParts -= 1
Frame.RedNumber.Text = tostring(RedParts)
end
OldColor = Part.BrickColor
BlueParts += 1
Frame.BlueNumber.Text = tostring(BlueParts)
end
end)
end
end
We’re good to go. I removed the first loop as you mentioned all of the parts start off as white.
I tried constructing a clean solution based on @tlr22 suggestion(when the color changes or a part is added/removed):
local RedParts = 0
local BlueParts = 0
function check(bc, operation) --BrickColor, operation = true for addition or false for subtraction
local red = BrickColor.new("Really red")
local blue = BrickColor.new("Really blue")
local num = (operation and 1) or -1 --brackets aren't needed, added them for clarity
if bc == red then
RedParts += num
elseif bc == blue then
BlueParts += num
end
end
function update() --runs when the amount of blue/red parts changes
print("Blue =", BlueParts, ", Red =", RedParts)
end
function DescendantAdded(object)
if not object:IsA("BasePart") then return end
local old = object.BrickColor
check(object.BrickColor, true)
object:GetPropertyChangedSignal("BrickColor"):Connect(function()
check(object.BrickColor, true)
check(old, false)
old = object.BrickColor
end)
update()
end
function DescendantRemoving(object)
if not object:IsA("BasePart") then return end
check(object.BrickColor, false)
update()
end
for _, object in pairs(workspace.Map:GetDescendants()) do
DescendantAdded(object)
end
update()
workspace.Map.DescendantAdded:Connect(DescendantAdded)
workspace.Map.DescendantRemoving:Connect(DescendantRemoving)