How to make the 2 last loops run at the same time

Code:

local CS = game:GetService("CollectionService")

local Colors ={
	Color3.fromHex("#c4281c"); -- Red
	Color3.fromHex("#ffff00"); -- Yellow
	Color3.fromHex("#00ff00"); -- Green
	Color3.fromHex("#0d69ac"); -- Blue
}

local db = false

-- Set Random

for _, Pad in pairs(CS:GetTagged("ColorDisplay")) do

	Pad.Color = Colors[math.random(1,#Colors)]

end

-- On Touch Set

for _, Pad in pairs(CS:GetTagged("ColorDisplay")) do
	
	Pad.Touched:Connect(function(hit)
		
		if hit.Parent:FindFirstChild("Humanoid") and db == false then
			
			Pad.Color = Colors[math.random(1,#Colors)]
			
			db = true
			
			task.wait(0.75)
			
			db = false
			
		end
		
	end)
	
end

-- Randomize Colors

local ColorChangeCooldown = false

local function RandomizeColors()

	while true do
		
		if ColorChangeCooldown == false then
			
			local ChosenColor1 = Colors[math.random(1,#Colors)]:ToHex()

			local ChosenColor2 = Colors[math.random(1,#Colors)]:ToHex()

			local ChosenColor3 = Colors[math.random(1,#Colors)]:ToHex()

			local ChosenColor4 = Colors[math.random(1,#Colors)]:ToHex()

			for _, ColorNum in pairs(CS:GetTagged("ColorNum")) do

				if string.sub(ColorNum.Name,ColorNum.Name:len()) == "1" then

					ColorNum.Text = "1. #" .. ChosenColor1

				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "2" then

					ColorNum.Text = "2. #" .. ChosenColor2

				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "3" then

					ColorNum.Text = "3. #" .. ChosenColor3

				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "4" then

					ColorNum.Text = "4. #" .. ChosenColor4

				end

			end
			
		end
		
		ColorChangeCooldown = true
		
		task.delay(180, function()
			
			ColorChangeCooldown = false
			
		end)
		
		task.wait()

	end

end

spawn(RandomizeColors())

local LaserBarrier = workspace:WaitForChild("Color Match Puzzle"):WaitForChild("LaserBarrier")

while true do
	
	print("123")
	
	local CorrectlyColoredPads = 0

	for _, Pad in pairs(CS:GetTagged("ColorDisplay")) do

		for _, ColorNum in pairs(CS:GetTagged("ColorNum")) do

			if Pad.Color:ToHex() == string.sub(ColorNum.Text,4) then

				CorrectlyColoredPads += 1

			end

		end

	end

	if CorrectlyColoredPads == 4 then

		for val = 0,0.7,0.1 do

			LaserBarrier.Transparency = val

			task.wait(0.01)

		end

		LaserBarrier.CanCollide = false

		task.wait(10)

		LaserBarrier.CanCollide = true		

		for val = 0.7,0,-0.1 do

			LaserBarrier.Transparency = val

			task.wait(0.01)

		end

	end

	task.wait(2)
	
end

I recommend using coroutine.
Docs: coroutine | Roblox Creator Documentation
Example:

coroutine.resume(coroutine.create(function()
	while true do
		--code
	end
end))
coroutine.resume(coroutine.create(function()
	while true do
		--code
	end
end))
3 Likes

where would i place this code?

Instead of your while true loops

coroutine.resume(coroutine.create(function()
	while true do
		if ColorChangeCooldown == false then
			local ChosenColor1 = Colors[math.random(1,#Colors)]:ToHex()
			local ChosenColor2 = Colors[math.random(1,#Colors)]:ToHex()
			local ChosenColor3 = Colors[math.random(1,#Colors)]:ToHex()
			local ChosenColor4 = Colors[math.random(1,#Colors)]:ToHex()

			for _, ColorNum in pairs(CS:GetTagged("ColorNum")) do
				if string.sub(ColorNum.Name,ColorNum.Name:len()) == "1" then
					ColorNum.Text = "1. #" .. ChosenColor1
				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "2" then
					ColorNum.Text = "2. #" .. ChosenColor2
				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "3" then
					ColorNum.Text = "3. #" .. ChosenColor3
				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "4" then
					ColorNum.Text = "4. #" .. ChosenColor4
				end
			end
		end
		ColorChangeCooldown = true
		task.delay(180, function()
			ColorChangeCooldown = false
		end)
		task.wait()
	end
end))

local LaserBarrier = workspace:WaitForChild("Color Match Puzzle"):WaitForChild("LaserBarrier")

coroutine.resume(coroutine.create(function()
	while true do
		print("123")
		local CorrectlyColoredPads = 0
		for _, Pad in pairs(CS:GetTagged("ColorDisplay")) do
			for _, ColorNum in pairs(CS:GetTagged("ColorNum")) do
				if Pad.Color:ToHex() == string.sub(ColorNum.Text,4) then
					CorrectlyColoredPads += 1
				end
			end
		end
		if CorrectlyColoredPads == 4 then
			for val = 0,0.7,0.1 do
				LaserBarrier.Transparency = val
				task.wait(0.01)
			end
			LaserBarrier.CanCollide = false
			task.wait(10)
			LaserBarrier.CanCollide = true		
			for val = 0.7,0,-0.1 do
				LaserBarrier.Transparency = val
				task.wait(0.01)
			end
		end
		task.wait(2)
	end
end))

I want this code to run the entire time

while true do
	
	print("123")
	
	local CorrectlyColoredPads = 0

	for _, Pad in pairs(CS:GetTagged("ColorDisplay")) do

		for _, ColorNum in pairs(CS:GetTagged("ColorNum")) do

			if Pad.Color:ToHex() == string.sub(ColorNum.Text,4) then

				CorrectlyColoredPads += 1

			end

		end

	end

	if CorrectlyColoredPads == 4 then

		for val = 0,0.7,0.1 do

			LaserBarrier.Transparency = val

			task.wait(0.01)

		end

		LaserBarrier.CanCollide = false

		task.wait(10)

		LaserBarrier.CanCollide = true		

		for val = 0.7,0,-0.1 do

			LaserBarrier.Transparency = val

			task.wait(0.01)

		end

	end

	task.wait(2)
	
end

And this code to run every 180 seconds

local function RandomizeColors()

	while true do
		
		if ColorChangeCooldown == false then
			
			local ChosenColor1 = Colors[math.random(1,#Colors)]:ToHex()

			local ChosenColor2 = Colors[math.random(1,#Colors)]:ToHex()

			local ChosenColor3 = Colors[math.random(1,#Colors)]:ToHex()

			local ChosenColor4 = Colors[math.random(1,#Colors)]:ToHex()

			for _, ColorNum in pairs(CS:GetTagged("ColorNum")) do

				if string.sub(ColorNum.Name,ColorNum.Name:len()) == "1" then

					ColorNum.Text = "1. #" .. ChosenColor1

				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "2" then

					ColorNum.Text = "2. #" .. ChosenColor2

				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "3" then

					ColorNum.Text = "3. #" .. ChosenColor3

				elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "4" then

					ColorNum.Text = "4. #" .. ChosenColor4

				end

			end
			
		end
		
		ColorChangeCooldown = true
		
		task.delay(180, function()
			
			ColorChangeCooldown = false
			
		end)
		
		task.wait()

	end

end

You just need to add coroutine. Look what I posted.

-- function that runs continuously
local function runContinuousCode()
	while true do
		print("123")
		-- The rest of your code goes here...
		-- Be sure to add wait() to avoid max CPU usage.
		wait(2)
	end
end

-- function that runs every 180 seconds
local function randomizeColors()
	while true do
		-- Your randomizeColors code goes here...
		wait(180)
	end
end

-- Start both functions in separate threads.
spawn(runContinuousCode)
spawn(randomizeColors)

should i remove this?

task.delay(180, function()
			ColorChangeCooldown = false
		end)

Yes, you have to remove it! let me know If It works

do i need the colorchange cooldown too?

No, Just do what I said, First code runs always. you do not have to change anything to first script!

Is it more optimized than Task.Spawn? or what difference does it make, and what is it used for instead of Task.Spawn? edit: just read more or less the documentation and if in doubt corutine is for more complex systems like what the OP is doing it is normally for more specific cycles and it makes a big difference.

What is the difference between task.delay and task.wait? edit: I’m stupid I realize it’s to put a few seconds to a function before it executes and the code continues as if nothing happened

coroutine is more flexible than task. task.spawn will just run until all the code has been executed, but coroutine you can stop and resume. In this case, you can also use task.spawn, there is no difference.

2 Likes

Will one be more optimized than the other?

I would not say, task.spawn and coroutine have the same optimization. coroutine is used for more complex scripts.

local CS = game:GetService("CollectionService")

local Colors ={
	Color3.fromHex("#c4281c"); -- Red
	Color3.fromHex("#ffff00"); -- Yellow
	Color3.fromHex("#00ff00"); -- Green
	Color3.fromHex("#0d69ac"); -- Blue
}

local db = false

-- On Touch Set

for _, Pad in pairs(CS:GetTagged("ColorDisplay")) do
	
	Pad.Touched:Connect(function(hit)
		
		if hit.Parent:FindFirstChild("Humanoid") and db == false then
			
			Pad.Color = Colors[math.random(1,#Colors)]
			
			db = true
			
			task.wait(0.75)
			
			db = false
			
		end
		
	end)
	
end

-- Randomize Colors

coroutine.resume(coroutine.create(function()
	
	while true do

		local ChosenColor1 = Colors[math.random(1,#Colors)]:ToHex()

		local ChosenColor2 = Colors[math.random(1,#Colors)]:ToHex()

		local ChosenColor3 = Colors[math.random(1,#Colors)]:ToHex()

		local ChosenColor4 = Colors[math.random(1,#Colors)]:ToHex()

		for _, ColorNum in pairs(CS:GetTagged("ColorNum")) do

			if string.sub(ColorNum.Name,ColorNum.Name:len()) == "1" then

				ColorNum.Text = "1. #" .. ChosenColor1

			elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "2" then

				ColorNum.Text = "2. #" .. ChosenColor2

			elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "3" then

				ColorNum.Text = "3. #" .. ChosenColor3

			elseif string.sub(ColorNum.Name,ColorNum.Name:len()) == "4" then

				ColorNum.Text = "4. #" .. ChosenColor4

			end

		end

		task.wait(180)

	end

end))

-- Check for solution

local LaserBarrier = workspace:WaitForChild("Color Match Puzzle"):WaitForChild("LaserBarrier")

local ColorPads = workspace:WaitForChild("Color Match Puzzle"):WaitForChild("ColorSetPads")

local ColorDisplays = workspace:WaitForChild("Color Match Puzzle"):WaitForChild("Floor"):WaitForChild("ColorNumDisplay").DisplayUI

coroutine.resume(coroutine.create(function()
	
	while true do
		
		print("Checking for solution...")
		
		if ColorPads.Pad1.Color:ToHex() == string.sub(ColorDisplays.ColorNum1.Text,5) and ColorPads.Pad2.Color:ToHex() == string.sub(ColorDisplays.ColorNum2.Text,5) and ColorPads.Pad3.Color:ToHex() == string.sub(ColorDisplays.ColorNum3.Text,5) and ColorPads.Pad4.Color:ToHex() == string.sub(ColorDisplays.ColorNum4.Text,5) then

			print("Solution found.")

			for val = 0,0.7,0.1 do

				LaserBarrier.Transparency = val

				task.wait(0.01)

			end
			LaserBarrier.CanCollide = false

			task.wait(10)

			LaserBarrier.CanCollide = true		

			for val = 0.7,0,-0.1 do

				LaserBarrier.Transparency = val

				task.wait(0.01)

			end

		end
		
		task.wait(1)
		
	end
	
end))

“Checking for solutions” only prints once (i did change my part of the script a little bc i encountered a bug)

This may be happening because of an error occurring within your coroutine, which would stop the loop from executing more than once.

In your script, this line could be causing an error:

if ColorPads.Pad1.Color:ToHex() == string.sub(ColorDisplays.ColorNum1.Text,5) and ColorPads.Pad2.Color:ToHex() == string.sub(ColorDisplays.ColorNum2.Text,5) and ColorPads.Pad3.Color:ToHex() == string.sub(ColorDisplays.ColorNum3.Text,5) and ColorPads.Pad4.Color:ToHex() == string.sub(ColorDisplays.ColorNum4.Text,5) then

The Color property is not valid for a Roblox part. If your “Pads” are BasePart objects, they will have a BrickColor property instead of Color. You should be using BrickColor, or if you want to use RGB colors you could store the color information in a StringValue or ObjectValue inside the part.

Also, the Color3 objects don’t have a ToHex() method. If you want to convert Color3 objects to a hex string, you will need to define your own function to do so.

To avoid silent failures of coroutines, you should wrap the body of your coroutine in a pcall function, which can capture errors and allow you to handle them.

coroutine.resume(coroutine.create(function()
    local success, err = pcall(function()
        -- your code here
    end)
    if not success then
        warn("Error in coroutine: " .. err)
    end
end))

This way, if there’s an error in your coroutine, you’ll see a warning in the output with the error message, and you can use this information to debug your script.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.