How do I wait in a task.spawn function?

script:

	for i, v in pairs(hit) do
			if v.Parent:FindFirstChild("Humanoid") then
				v.Parent.Humanoid.Health = v.Parent.Humanoid.Health - 10
				local direction = (v.Parent:FindFirstChild("HumanoidRootPart").Position - range.Position).unit
				task.spawn(function()
					local KnockBack = Instance.new("BodyVelocity")
					KnockBack.Parent = v.Parent.HumanoidRootPart 
			
					
					KnockBack.MaxForce = Vector3.new(1000,1000,1000)
					KnockBack.Velocity = direction * 100

					task.wait(3)
					v.Parent.HumanoidRootPart.BodyVelocity:Destroy()
					print("yep")
					
					v.Parent.RagdollTrigger.Value = true
				end)
			
			break
			end
		end

when i add a task.wait or a wait, it stops there and doesn’t do anything again, how would i wait in this function?

Are there any errors in the output? Without further information, it may be too difficult to help you. Additionally, I’d recommend looking into Coroutines as I’ve heard they’re more performant. (Still yet to test that myself, though.)

zero errors at all, i perfer task.spawn since it does minimal changes on my code and works fine, but I can use it if it is the only option

task.spawn() works perfectly fine in your cenario if you’re more comfortable with the Task Library!

After a second review of your code, it seems like you’re breaking out of the code after processing the first hit. This means that the loop won’t continue to the next iteration, and may cause the unexpected behavior you were experiencing.

In other words, if the first iteration doesn’t turn up the results you wanted, it will still break out of the loop.

To solve this, just simply try removing the break out of the loop.

for i, v in ipairs(hit) do
    if v.Parent:FindFirstChild("Humanoid") then
        v.Parent.Humanoid.Health = v.Parent.Humanoid.Health - 10
        local direction = (v.Parent:FindFirstChild("HumanoidRootPart").Position - range.Position).unit

        task.spawn(function()
            local KnockBack = Instance.new("BodyVelocity")
            KnockBack.Parent = v.Parent.HumanoidRootPart 
            KnockBack.MaxForce = Vector3.new(1000, 1000, 1000)
            KnockBack.Velocity = direction * 100

            task.wait(3)

            -- Destroy the BodyVelocity after the wait
            KnockBack:Destroy()
            print("yep")

            v.Parent.RagdollTrigger.Value = true
        end)
    end
end

If that doesn’t fix your issue, it may be something related to other code you have in your script.

Another possibility: This seems to be code for a hit detection system, right? Instead of a loop, maybe just check if the hit.Parent turns up a Humanoid. That could very well solve your issue if that’s the case.

first of all, nope, the break doesn’t do anything as far as i am aware, why do i know this? because i did it before AND there is a second function that is exactly that without the break.

	local hit = workspace:GetPartsInPart(range)
		for i, v in pairs(hit) do
			if v.Parent:FindFirstChild("Humanoid") then
				v.Parent.Humanoid.Health = v.Parent.Humanoid.Health - 10
				local direction = (v.Parent:FindFirstChild("HumanoidRootPart").Position - range.Position).unit
				task.spawn(function()
					local KnockBack = Instance.new("BodyVelocity")
					KnockBack.Parent = v.Parent.HumanoidRootPart 
			
					
					KnockBack.MaxForce = Vector3.new(1000,1000,1000)
					KnockBack.Velocity = direction * 100

					task.wait(3)
					v.Parent.HumanoidRootPart.BodyVelocity:Destroy()
					print("yep")
					
					v.Parent.RagdollTrigger.Value = true
				end)
			
			
			end
		end
		for i, v in pairs(hit) do
			if v.Parent.Name == "OBJS" then
				local direction = (v.Position - range.Position).unit

				task.spawn(function()
					local KnockBack = Instance.new("BodyVelocity")
					KnockBack.Parent = v --part is the target of the knockback/ the opponent

					KnockBack.MaxForce = Vector3.new(5000,5000,5000)
					KnockBack.Velocity = direction * 200

					task.wait(0.2)
					KnockBack:Destroy()
				end)
			
			
			end
		end
		script.Parent.Parent:Destroy()
		break
	end
end

and the reason i am using touch.spawn is because this is an explosion, it happens instantly, task.spawn allows it to go faster without the explosion delaying too much

And you’re absolutely confident the code in task.spawn() even runs?

100% confidant
if i remove the task.wait it works fine

Are you by chance destroying this script or any of its ancestors?

Edit: ok you are, try task.defer instead of task.spawn