How to run two loops at once

Hi. Im trying to make a game where there are moving parts which kill you upon touch. I know I can just add a script onto the part which moves its position, but I want to know if there is any way to do it with just 1 script.

while task.wait(1) do
	local part = Instance.new("Part")
	part.Size = Vector3.new(101.5,1,1)
	part.Parent = workspace
	part.Touched:Connect(function(hit)
		local hum = hit.Parent:FindFirstChild("Humanoid")
		if hum then
			hum.Health = 0
		end
	end)
	
	while task.wait(0.1) do
		part.Position += Vector3.new(0,1,0)
	end
	
end``` 
I saw some forums about things called "coroutines", but I dont know how to use it since im still learning. Any help would be greatly appreciated!
while task.wait(1) do
	local part = Instance.new("Part")
	part.Size = Vector3.new(101.5,1,1)
	part.Parent = workspace
	part.Touched:Connect(function(hit)
		local hum = hit.Parent:FindFirstChild("Humanoid")
		if hum then
			hum.Health = 0
		end
	end)
	
	while task.wait(0.1) do
		part.Position += Vector3.new(0,1,0)
	end
	
end

To wrap a function like this in corutine, do

coroutine.wrap(function()
while task.wait(1) do
	local part = Instance.new("Part")
	part.Size = Vector3.new(101.5,1,1)
	part.Parent = workspace
	part.Touched:Connect(function(hit)
		local hum = hit.Parent:FindFirstChild("Humanoid")
		if hum then
			hum.Health = 0
		end
	end)
	
	while task.wait(0.1) do
		part.Position += Vector3.new(0,1,0)
	end
	
end
end)()

adding the () at the end makes it run instantly

Yeah, coroutines will help you a lot, you can do

local PartCreation = coroutine.create(function() -- create the coroutine function to use
       while task.wait(1) do
	        local part = Instance.new("Part")
	        part.Size = Vector3.new(101.5,1,1)
          	part.Parent = workspace

	        part.Touched:Connect(function(hit)
		       local hum = hit.Parent:FindFirstChild("Humanoid")
		       if hum then
		   	     hum.Health = 0
		      end
	       end)
	
	       coroutine.wrap(function() -- it's like coroutine.create, but it's a instant function instead!!
		      part.Position += Vector3.new(0,1,0)
	       end)
	end
end)

coroutine.resume(PartCreation)

i didn’t test it tho

mind explaining how coroutines work? sorry for the inconvenience but i tried looking it up and im still pretty confused on how they work(for future references)

You don’t need coroutine at all, only a single loop is enough.

i know, its just i want to know how coroutines work, since im still pretty new to roblox studio

Coroutines are creating a new thread, it is same as if you were creating a new script to run the part of code you want into it, so if there is a wait time or a loop into your script, running the code into a coroutine avoid to yield (stuck) the script and the rest of the code will still run.

In your case you don’t need coroutine at all, because it will stack up a new loop for every part and it will decrease performances a lot.
Here is the code you need which is much more performant.

local CreatePartCooldown = 1
local partList = {}

local function KillCharacter(hit)
	local hum = hit.Parent:FindFirstChild("Humanoid")	
	if hum then
		hum.Health = 0
	end
end

local function CreatePart()
	local part = Instance.new("Part")	
	part.Size = Vector3.new(101.5,1,1)
	part.Parent = workspace
	table.insert(partList, part)
	part.Touched:Connect(KillCharacter)
end

while task.wait(0.1) do
	if CreatePartCooldown <= 0 then
		CreatePart()
		CreatePartCooldown = 1
	else
		CreatePartCooldown -= 0.1
	end
	
	for _, part in pairs(partList) do
		part.Position += Vector3.new(0,1,0)
	end
end
1 Like