How would I loop this Corountine?

So I’m obviously new to coroutines and I’m developing (not really I’m just toying around with it) one of those pixel art rpg-esqe mmo games and this is the system that changes the sprite when you walk.

The problem here is that when you walk once and then let go of the S key, it won’t do it again. I’ve looked up multiple devforum posts and nothing helped. Here’s the original script so you won’t get confused.

wait()
local UserInputService = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local character = player.Character
local sprite = character.Sprite.CurrentSprite
local walkfront = {9876962910, 9876968509, 9876969293, 9876968509}

local walkfrontanim = function() --this is the function that gets called by the coroutine
	repeat
			for e,value in pairs(walkfront) do
				sprite.Texture = "rbxassetid://".. value
				wait(0.1)
	end
	until not UserInputService:IsKeyDown(Enum.KeyCode.S)

end

local corowfa = coroutine.create(walkfrontanim) -- coroutine

UserInputService.InputBegan:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.S then
		coroutine.resume(corowfa) -- where it gets triggered
	end
end)

Any help would be appreciated.

2 Likes

just put another loop

local walkfrontanim = function()
	while true do
		repeat
			for Index, Value in pairs(walkfront) do
				sprite.Texture = "rbxassetid://"..Value
				task.wait(0.2)
			end
		until not UserInputService:IsKeyDown(Enum.KeyCode.S)
		coroutine.yield()
	end
end
1 Like

You’ve got too many ends. Also I think the repeat should be removed and replaced with an if statement. As it is, it will always run even if the key isn’t down.

1 Like

repeat loop until key “S” is not held and while true do to repeat this every time coroutine is resumed

As @V_ladzec showed, you could put a loop inside of another loop; or a more efficient way to do it is, have the function repeat until the Key is no longer pressed down.
As @V_ladzec showed;

repeat
	for Index, Value in pairs(walkfront) do
		sprite.Texture = "rbxassetid://"..Value
		wait(0.2) --No need to use task wait here.
	end
until not UserInputService:IsKeyDown(Enum.KeyCode.S) --No idea if this works like this, go ahead and try it though.

For the coroutine wrap, just do the following;

repeat
	for Index, Value in pairs(walkfront) do
		coroutine.wrap(function() 
			sprite.Texture = "rbxassetid://"..Value
			wait(0.2) --No need to use task wait here.
		end)()
	end
until not UserInputService:IsKeyDown(Enum.KeyCode.S) --No idea if this works like this, go ahead and try it though.

To run your function, you could do something like this;

UserInputService.InputBegan:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.S then
		RunAnimFunction()
	end
end)

End Result

local UserInputService = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local character = player.Character
local sprite = character.Sprite.CurrentSprite
local walkfront = {9876962910, 9876968509, 9876969293, 9876968509}

function RunAnimFunction()
	repeat
		for Index, Value in pairs(walkfront) do
			coroutine.wrap(function() 
				sprite.Texture = "rbxassetid://"..Value
				wait(0.2) --No need to use task wait here.
			end)()
		end
	until not UserInputService:IsKeyDown(Enum.KeyCode.S) --No idea if this works like this, go ahead and try it though.
end


UserInputService.InputBegan:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.S then
		RunAnimFunction()
	end
end)

studio froze and script timed out, I’m guessing it has to be something with multiple coroutines getting created during in pairs but might be wrong on that.

No, you’re right; my apologies… add another wait time after the coroutine.wrap ends.

function RunAnimFunction()
	repeat
		for Index, Value in pairs(walkfront) do
			coroutine.wrap(function() 
				sprite.Texture = "rbxassetid://"..Value
				wait(0.2) --No need to use task wait here.
			end)()
			wait(.2)
		end
	until not UserInputService:IsKeyDown(Enum.KeyCode.S) --No idea if this works like this, go ahead and try it though.
end

like that^

1 Like

Here’s a video on what I’m trying to do. (Basically trying to get the coroutine to play again whilst i think it’s dead)
robloxapp-20220611-0702475.wmv (1.5 MB)
)

1 Like

Works perfectly, i appreciate your help.

2 Likes

oh then, you most likely won’t need the coroutine.wrap at all. You should then just change it to the following;

function RunAnimFunction()
	repeat
		for Index, Value in pairs(walkfront) do
			--coroutine.wrap(function() 
				sprite.Texture = "rbxassetid://"..Value
				--wait(0.2) --No need to use task wait here.
			--end)()
			wait(.2)
		end
	until not UserInputService:IsKeyDown(Enum.KeyCode.S) --No idea if this works like this, go ahead and try it though.
end