So I’m trying to make my own idle animation system. I know I can make it easier with animator.AnimationPlayed:Connect() but I just don’t like the timing of the normal one.
My problem is that the animation only plays once, then never again. Everything else seems to be working fine, it starts every 20 secs and waits the random timing. The output also prints everything but the animation just doesn’t play.
Here’s my script:
local animation = Instance.new("Animation")
local runIdleAnimations = coroutine.create(function()
local randomTiming = math.random(5, 15)
while true do
if character.PrimaryPart.AssemblyLinearVelocity.Magnitude < 1 then
print("Checking if Player is Idle")
wait(randomTiming)
if character.PrimaryPart.AssemblyLinearVelocity.Magnitude < 1 then
print("Player Confirmed Idle")
animation.AnimationId = idleAnimations[math.random(1, #idleAnimations)]
local animationTrack = animator:LoadAnimation(animation)
animationTrack.Priority = Enum.AnimationPriority.Idle
animationEnded = false
coroutine.resume(followHeadCam)
animationTrack:Play()
animationTrack.Ended:Wait()
print("Animation Ended")
humanoid.AutoRotate = true
camera.CameraType = Enum.CameraType.Custom
camera.CameraSubject = humanoid
animationEnded = true
else
print("Player is not Idle")
end
randomTiming = math.random(1, 5)
end
wait(20)
end
end)
coroutine.resume(runIdleAnimations)
I ran this script and it worked. It is just a modified version of your script, but with the basic wave animation.
local character = game.Players.LocalPlayer.Character
local animation = script.WaveAnim
local hum = character:FindFirstChild("Humanoid")
local runIdleAnimations = coroutine.create(function()
local randomTiming = math.random(2, 3)
while true do
if character.PrimaryPart.AssemblyLinearVelocity.Magnitude < 1 then
print("Checking if Player is Idle")
wait(randomTiming)
if character.PrimaryPart.AssemblyLinearVelocity.Magnitude < 1 then
print("Player Confirmed Idle")
local animationTrack = hum.Animator:LoadAnimation(animation)
animationTrack.Priority = Enum.AnimationPriority.Idle
animationTrack.Looped = false
animationTrack:Play()
animationTrack.Ended:Wait()
print("Animation Ended")
else
print("Player is not Idle")
end
randomTiming = math.random(1, 5)
end
wait(2)
end
end)
coroutine.resume(runIdleAnimations)
Make sure to add
animationTrack.Looped = false
to your script.
Apart from this, the script you have is correct, so something else must be the source of error.
Did that but it’s the same, maybe its the coroutine that I’m playing just before playing the animation?
local followHeadCam = coroutine.create(function()
for i,v in character:GetChildren() do -- makes any vision blocking accessory invisible
if v:IsA("Accessory") then
v.Handle:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function()
v.Handle.LocalTransparencyModifier = 1
end)
v.Handle.LocalTransparencyModifier = v.Handle.Transparency
end
end
humanoid.AutoRotate = false
camera.CameraType = Enum.CameraType.Scriptable
camera.CameraSubject = character.Head
while animationEnded == false do
camera.CFrame = character.Head.CFrame
print("Following Head..")
runService.RenderStepped:Wait()
end
end)
Once a coroutine function finishes executing after coroutine.resume, coroutine.resume does not work again. Here is a source covering coroutines: coroutine | Documentation - Roblox Creator Hub.
I’m looking into work arounds though.
Okay, I’ve figured it out. This post shows a work around: How do I make coroutines run from the start every time it's called?.
I’m not sure if there is a better way to do this, as I have been focusing on other coding languages recently, and am not up-to-date with the most recent APIs.
Yeah that’s what I did just now. Placed it inside the while loop so that it creates a new coroutine every time. Did not know that coroutines only play once though, thanks.