I’m hoping to achieve a way to start animation frame loops and stop them when inputs are stopped.
How I have it now, the frames loop from a while loop that tests for the inputs and when there isn’t any, the loop will stop and it’ll display the unmoving image.
while wait() do
if dir1 or dir2 then
for i,v in pairs(frameInfo) do
wait(frameDelay)
characterLabel.Image = v
end
else
characterLabel.Image = stillFrame
end
end
And I know this is a terribly inefficient way to do it but I couldn’t think of another way that worked in testing. I’ve tried using other types of loops, read about coroutine and spawn things but I couldn’t get that working. The closest thing I think that could suit my needs would be using the coroutine:yield() when the inputs stop but I can’t start the loop function in the first place at least with how much I know currently.
Another issue with this method I’m using now is that the frames will continue to the end of the animation loop to stop. I was hoping if anyone out there knows more about coroutines than me would know if using coroutines would remedy this also.
Not quite sure I understand what you’re trying to achieve or fix but couldn’t you just add an if statement within the actual for loop (not the while loop). That way every time it runs, it would check to see if a certain value is true and you go from there.
For example, something like this:
Note the below is just a rough draft to give you an idea, it may have typos, etc.
local canAnimate = true
function animateFrame(frameInfo)
for i, v in pairs(frameInfo) do
if canAnimate then -- Check if it can animate and if true allows the animation to continue
wait(frameDelay)
characterLabel.Image = v
else -- If false, the animation will default to this
characterLabel.Image = stillFrame
end;
end;
end;
-- Lets pretend the user input starts
canAnimate = true
animateFrame(theFrameInfo)
-- Lets pretend the user input stops
canAnimate = false -- If the loop is still running it should turn back to stillFrame instead of animating
characterLabel.Image = stillFrame
If this isn’t what you wanted, could please send a gif of how its currently working so I can get a better idea of what you need.
local uis = game:GetService("UserInputService")
local run = game:GetService("RunService")
local character = script.Parent
local characterLabel = character:FindFirstChild("HumanoidRootPart").SurfaceGui.characterLabel
local keybinds = {
[Enum.KeyCode.W] = "up";
[Enum.KeyCode.S] = "down";
[Enum.KeyCode.A] = "left";
[Enum.KeyCode.D] = "right";
}
local prefix = "http://www.roblox.com/asset/?id="
local stillFrame = prefix.."----"
local frameInfo = {
prefix.."----";
prefix.."----";
prefix.."----";
prefix.."----";
}
local frameDelay = 0.1
local dir1 = nil
local dir2 = nil
uis.InputBegan:Connect(function(data)
local var = keybinds[data.KeyCode]
if var == "up" then
if dir1 ~= "up" then
if dir1 == nil then
dir1 = "up"
else
dir2 = "up"
end
end
elseif var == "down" then
if dir1 ~= "down" then
if dir1 == nil then
dir1 = "down"
else
dir2 = "down"
end
end
elseif var == "left" then
if dir1 ~= "left" then
if dir1 == nil then
dir1 = "left"
else
dir2 = "left"
end
end
elseif var == "right" then
if dir1 ~= "right" then
if dir1 == nil then
dir1 = "right"
else
dir2 = "right"
end
end
end
end)
uis.InputEnded:Connect(function(data)
local var = keybinds[data.KeyCode]
if var == "up" then
if dir1 == "up" then
dir1 = nil
elseif dir2 == "up" then
dir2 = nil
end
end
if var == "down" then
if dir1 == "down" then
dir1 = nil
elseif dir2 == "down" then
dir2 = nil
end
end
if var == "left" then
if dir1 == "left" then
dir1 = nil
elseif dir2 == "left" then
dir2 = nil
end
end
if var == "right" then
if dir1 == "right" then
dir1 = nil
elseif dir2 == "right" then
dir2 = nil
end
end
end)
local walking
run.RenderStepped:Connect(function()
if dir1 or dir2 then
walking = true
if dir1 == "up" or dir1 == "down" then
if dir2 == "up" or dir2 == "down" then
walking = false
end
elseif dir1 == "left" or dir1 == "right" then
if dir2 == "left" or dir2 == "right" then
walking = false
end
end
else
walking = false
end
print(walking)
end)
If it helps, this is my current layout for the script. Basically, the player’s given two available movement slots, dir1 and dir2. This is to keep the animation going if two keys are pressed at the same time and then it switches to only one key.
I already have everything working how I want it, the print in the run.RenderStepped is giving me all the values I want consistently and all I need to do now is convert that bool into the status or cycle or the animation loop. Hopefully, if the player stops the anim will stop and reset but if they hold it for longer, it will stay with the bool value and keep looping.
If I’m understanding you correctly than you should be able to use your while loop but instead add an if statement for the walking bool.
Like so:
while wait() do
if dir1 or dir2 then
for i,v in pairs(frameInfo) do
if walking == true then -- If player is walking than continue animation
wait(frameDelay)
characterLabel.Image = v
else -- If player isn't walking revert to still frame
characterLabel.Image = stillFrame
end;
end
else
characterLabel.Image = stillFrame
end
end