Coroutine.status returns "suspended" on my running coroutine

This is my code:

local secondsStunned = 0
local hitThread = coroutine.create(function(char)
	local plr = game:GetService("Players"):GetPlayerFromCharacter(char)
	if plr then
		if plr.Team ~= game:GetService("Teams").Chaser then
			return
		end
	end
	
	while true do
		print(secondsStunned)
		if not char then secondsStunned = 0 return end
		local hrp = char:FindFirstChild("HumanoidRootPart")
		if secondsStunned > 0 then
			if hrp then
				hrp.Anchored = true
				secondsStunned -= 1
			end
		else
			if hrp then
				hrp.Anchored = false
				coroutine.yield()
			end
		end
		wait(1)
	end
end)

function Hit(Character)
	secondsStunned += 10
	
	print(coroutine.status(hitThread))
	if coroutine.status(hitThread) ~= "running" then
		coroutine.resume(hitThread, Character)
	end
end

First time I hit, it prints “suspended” which is what should happen but when it’s counting, I hit once more and it prints “suspended” again and runs it once more which results in a faster counting. What am I doing wrong here?

2 Likes

Just make hitThread a function and call coroutine.wrap(hitThread)() instead

1 Like

I would recommend removing return as it stops the rest of the script in the same scope from running (if the previous statement, if plr.Team ~= game:GetService("Teams").Chaser then. If the code finishes running I believe it will be suspended, but I’m probably wrong about this:

print("Started") -- prints
if true then
    return
end
print("Passed") -- doesn't print
print("Started") -- prints
if true == false then
    return
end
print("Passed") -- prints
1 Like

There is that return because I don’t want that function to run in that case.

It’ll be dead.

1 Like

The coroutine can only run once and then it’s dead. I suggest making a new thread each time with the same function. You have to do what I said before in order to get the result that you want.

Nope, didn’t work. Does the same with mine.

Well this is expected behavior, if a coroutine wasn’t coroutine.resumed during the period it’s not running it will be "suspended". A coroutine is running if it was resumed. I suggest simply creating the coroutine inside of Hit and resuming it, scrapping the "running" check.

I think you didn’t read what I said. It’s getting resumed in first hit and then secons still reads it as suspended.

I tried some more methods but nothing worked, this topic is still active.

I know this is way late but
Something like

local shouldrun = true
local running = false
local ended =  false
local secondsStunned = 0
function hitThreadF()
	running = true
	local plr = game:GetService("Players"):GetPlayerFromCharacter(char)
	if plr then
		if plr.Team ~= game:GetService("Teams").Chaser then
			return
		end
	end

	while shouldrun do
		print(secondsStunned)
		if not char then secondsStunned = 0 return end
		local hrp = char:FindFirstChild("HumanoidRootPart")
		if secondsStunned > 0 then
			if hrp then
				hrp.Anchored = true
				secondsStunned -= 1
			end
		else
			if hrp then
				hrp.Anchored = false
				coroutine.yield()
			end
		end
		wait(1)
	end
	ended = true
end
hitThread = coroutine.create(hitThreadF)
function Hit(Character)
	secondsStunned += 10

	if not running then
		coroutine.resume(hitThread, Character)
	--else -- To stop it
		--shouldrun = false
		--running = false
		--repeat task.wait() until ended
		--hitThread = coroutine.create(hitThreadF)
		--ended = false
		--shouldrun = true
	end
end

should work