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

How to prevent ipair loops freezing functions?

SO I have a for i, v in ipairs(game.Workspace:GetChildren()) do, and it freezes up the rest of the function. How do I fix this? This is in a server script if you're wondering.

function Shoot()
	for i, v in ipairs(game.Workspace:GetChildren()) do
		torson = v:WaitForChild("Torso") or v:WaitForChild("HumanoidRootPart")
	end
	script.Parent.Blast:Play()
	local bullet = Instance.new("Part",workspace)
	bullet.Size = Vector3.new(0.1,0.5,0.1)
	bullet.BrickColor = BrickColor.new("Gold")
	bullet.Velocity = myTorso.CFrame.lookVector * 400
	bullet.CFrame = CFrame.new(script.Parent.Unit1.Position, torson.Position)
	bullet.CanCollide = false
	bullet.Touched:Connect(function(obj)
		if not obj:IsDescendantOf(script.Parent) then 
			local human = obj.Parent:FindFirstChild("Humanoid")
			if human then
				human:TakeDamage(45)
			end
			bullet:Destroy()
		end
	end)
	
	game:GetService("Debris"):AddItem(bullet, 5)
end

Thanks in advance!

1 comment

0

What is "torson" supposed to do?

2 answers

✓ Accepted answer

The reason it is freezing (I think) Is the script is waiting for Torso and HumanoidRootPart in the model which does not contain them (Not Character model), so it will stop the function forever. So there is 2 way to fix it is to change WaitForChild to FindFirstChild

function Shoot()
    for i, v in ipairs(game.Workspace:GetChildren()) do
        torson = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
    end
    script.Parent.Blast:Play()
    local bullet = Instance.new("Part",workspace)
    bullet.Size = Vector3.new(0.1,0.5,0.1)
    bullet.BrickColor = BrickColor.new("Gold")
    bullet.Velocity = myTorso.CFrame.lookVector * 400
    bullet.CFrame = CFrame.new(script.Parent.Unit1.Position, torson.Position)
    bullet.CanCollide = false
    bullet.Touched:Connect(function(obj)
        if not obj:IsDescendantOf(script.Parent) then 
            local human = obj.Parent:FindFirstChild("Humanoid")
            if human then
                human:TakeDamage(45)
            end
            bullet:Destroy()
        end
    end)

    game:GetService("Debris"):AddItem(bullet, 5)
end

Or add a WaitForChild timeout

function Shoot()
    for i, v in ipairs(game.Workspace:GetChildren()) do
        torson = v:FindFirstChild("Torso",2) or v:FindFirstChild("HumanoidRootPart",2) -- The script will skip it if it cannot find after 2 sec
    end
    script.Parent.Blast:Play()
    local bullet = Instance.new("Part",workspace)
    bullet.Size = Vector3.new(0.1,0.5,0.1)
    bullet.BrickColor = BrickColor.new("Gold")
    bullet.Velocity = myTorso.CFrame.lookVector * 400
    bullet.CFrame = CFrame.new(script.Parent.Unit1.Position, torson.Position)
    bullet.CanCollide = false
    bullet.Touched:Connect(function(obj)
        if not obj:IsDescendantOf(script.Parent) then 
            local human = obj.Parent:FindFirstChild("Humanoid")
            if human then
                human:TakeDamage(45)
            end
            bullet:Destroy()
        end
    end)

    game:GetService("Debris"):AddItem(bullet, 5)
end

Hope that helped

1 comment

0

Thanks dude!

A function call waits for the thread (the function in this case) to end. To bypass this, either use BindableEvents, Modulescripts, or coroutines. All of these used correctly can work as multi-threaded.

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