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

How do I make a loop run if it has a loop within it?

I have a loop that creates a brick every 2 seconds, but there's a loop within it that changes the brick color randomly. Is there any way of making both of them loop? For reference:

wait(1)
workspace:WaitForChild("PartStorage")
while true do
	wait(2)
	local part = Instance.new("Part",workspace.PartStorage)
	local cash = Instance.new("IntValue",part)
	cash.Name = "Cash"
	cash.Value = 50
	part.CFrame = script.Parent.Dropper.CFrame - Vector3.new(0,1,0)
	part.Size=Vector3.new(1,1,1)
	part.LeftSurface=("Studs")
	part.RightSurface=("Studs")
	part.FrontSurface=("Studs")
	part.BackSurface=("Studs")
	part.TopSurface=("Studs")
	part.BottomSurface=("Studs")
	while true do
		part.BrickColor = BrickColor.Random()
		wait(.5)
		end
	part.Name=("Rainbow Brick")
	game.Debris:AddItem(part,8)
end

4 answers

✓ Accepted answer

One option is to use Spawn, but coroutines are generally better, because they do not delay.

wait(1)
workspace:WaitForChild("PartStorage")
while true do
    wait(2)
    local part = Instance.new("Part",workspace.PartStorage)
    local cash = Instance.new("IntValue",part)
    cash.Name = "Cash"
    cash.Value = 50
    part.CFrame = script.Parent.Dropper.CFrame - Vector3.new(0,1,0)
    part.Size=Vector3.new(1,1,1)
    part.LeftSurface=("Studs")
    part.RightSurface=("Studs")
    part.FrontSurface=("Studs")
    part.BackSurface=("Studs")
    part.TopSurface=("Studs")
    part.BottomSurface=("Studs")
    coroutine.resume(coroutine.create(function()
        while true do
            part.BrickColor = BrickColor.Random()
            wait(.5)
        end
    end))
    part.Name=("Rainbow Brick")
    game.Debris:AddItem(part,8)
end

You can use the spawn function begin running a function "in the background".

It would look like this:

spawn(function()
	while true do
		part.BrickColor = BrickColor.Random()
		wait(0.5)
	end
end)

However, this isn't very efficient. Lots of spawns happening will bog down all of your scripts.

Instead, you can get away with just one spawn, by updating all of the bricks at once:

spawn(function()
	while true do
		for _, part in pairs(workspace:WaitForChild("PartStorage")) do
			part.BrickColor = BrickColor.Random()
		end
		wait(0.5)
	end
end)

while true do
	wait(2)
	local part .....

A simple delay functiom should work:



	wait(1)
	workspace:WaitForChild("PartStorage")
	while true do
	    wait(2)
	    local part = Instance.new("Part",workspace.PartStorage)
	    local cash = Instance.new("IntValue",part)
	    cash.Name = "Cash"
	    cash.Value = 50
	    part.CFrame = script.Parent.Dropper.CFrame - Vector3.new(0,1,0)
	    part.Size=Vector3.new(1,1,1)
	    part.LeftSurface=("Studs")
	    part.RightSurface=("Studs")
	    part.FrontSurface=("Studs")
	    part.BackSurface=("Studs")
	    part.TopSurface=("Studs")
	    part.BottomSurface=("Studs")
	    delay(0, function() while true do
	        part.BrickColor = BrickColor.Random()
	        wait(.5)
	        end end)
	    part.Name=("Rainbow Brick")
	    game.Debris:AddItem(part,8)
	end

As I do agree with aquathorn321 I would use coroutine.wrap() instead

wait(1)
workspace:WaitForChild("PartStorage")
local parts = {}
workspace.PartStorage.ChildRemoved:connect(function(par)
-- check if part is in table
local isInTable = false
local gtPart = nil
for _, v in pairs(parts) do
 if v.name == par.Name then
isInTable = true
gtPart = v
end
end

if isInTable then
table.remove(parts, gtPart.id)
end
end)

local changePart = coroutine.wrap(function()
for _, v in pairs(parts) do
workspace.PartStorage:FindFirstChild(v.name).BrickColor = BrickColor.Random()
end
end)
changePart()
while true do
    wait(2)
    local part = Instance.new("Part",workspace.PartStorage)
    local cash = Instance.new("IntValue",part)
    cash.Name = "Cash"
    cash.Value = 50
    part.CFrame = script.Parent.Dropper.CFrame - Vector3.new(0,1,0)
    part.Size=Vector3.new(1,1,1)
    part.LeftSurface=("Studs")
    part.RightSurface=("Studs")
    part.FrontSurface=("Studs")
    part.BackSurface=("Studs")
    part.TopSurface=("Studs")
    part.BottomSurface=("Studs")
    part.Name=("Rainbow Brick")
	local newID = #parts+1
	parts[newID] = {id = newID, name = part.Name}
    game.Debris:AddItem(part,8)
end

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