Animations won't stop

Hello!
I’m trying to make a shield that goes up and down, however the previous animations don’t stop playing (even after deleting/stop() ).

Any help would be appreciated!

local function lower2()
	if stancevalue == 1 then
		script.Parent.Holding.Value = false
		stancevalue = 0
		local animation = Instance.new("Animation")
		animation.Name = "ToIdle"
		animation.Parent = script.Parent

		animation.AnimationId = "http://www.roblox.com/asset/?id=8625656398"
		local animtrack = humanoid:LoadAnimation(animation)
		animtrack:Play()
		wait(0.17)
		animtrack:Stop() -- Destroy() Doesn't work either. 
	elseif stancevalue == 2 then
		script.Parent.Stance2:Destroy()
		stancevalue = 1
		local animation = Instance.new("Animation")
		animation.Name = "ToStance1"
		animation.Parent = script.Parent

		animation.AnimationId = "http://www.roblox.com/asset/?id=8625657640"
		local animtrack = humanoid:LoadAnimation(animation)
		animtrack:Play()
		wait(0.17)
		animtrack:Stop() -- Destroy() Doesn't work either. 
		local animation2 = Instance.new("Animation")
		animation2.Name = "Stance1"
		animation2.Parent = script.Parent

		animation.AnimationId = "http://www.roblox.com/asset/?id=8625647558"
		local animtrack2 = humanoid:LoadAnimation(animation)
		animtrack2:Play()
	end
end

(Apologies in advanced for the scripting I’m quite new)

1 Like

This is what happens with the above script:
output gif

Are the animations set as looped

No, animations aren’t set as looped.

have you tried testing this in the actual roblox client?? i heard animations can get buggy in studio but work just fine in-game.

I’ve tried in game and it still doesn’t work.

you should play the anims using the animator thing, not humanoid

local function lower2()
	if stancevalue == 1 then
		script.Parent.Holding.Value = false
		stancevalue = 0
		local animation = Instance.new("Animation")
		animation.Name = "ToIdle"
		animation.Parent = script.Parent

		animation.AnimationId = "http://www.roblox.com/asset/?id=8625656398"
		local Animator = humanoid:FindFirstChildOfClass("Animator")
		if Animator then
			local animtrack = Animator:LoadAnimation(animation)		
			animtrack:Play()
			wait(0.17)
			animtrack:Stop() -- Destroy() Doesn't work either. 
		end
	
	
	elseif stancevalue == 2 then
		script.Parent.Stance2:Destroy()
		stancevalue = 1
		local animation = Instance.new("Animation")
		animation.Name = "ToStance1"
		animation.Parent = script.Parent

		animation.AnimationId = "http://www.roblox.com/asset/?id=8625657640"
		local Animator = humanoid:FindFirstChildOfClass("Animator")
		if Animator then
			local animtrack = Animator:LoadAnimation(animation)		
			animtrack:Play()
			wait(0.17)
			animtrack:Stop() -- Destroy() Doesn't work either. 
	
		animation.AnimationId = "http://www.roblox.com/asset/?id=8625647558"
		local animtrack2 = Animator:LoadAnimation(animation)
			animtrack2:Play()
		end
	end
end

also full script plz

Each time the function is executed you are re-instancing the same AnimationTrack by calling the instance method “:LoadAnimation” on the Humanoid instance and passing to it the same Animation object. To avoid this, declare a variable for each AnimationTrack instance before and outside of the function and load each there instead.

--declare a variable for the animation here as a non-local to the function

local animation = Instance.new("Animation")
animation.Parent = script.Parent
local animtrack = nil

local function loadAndPlayAnim(animId, animName)
	animation.Name = animName
	animation.AnimationId = "rbxassetid://"..animId
	animtrack = nil
	animtrack = humanoid:LoadAnimation(animation)
	repeat
		task.wait()
	until animtrack.Length > 0
	animtrack:Play()
	task.wait(0.17)
	animtrack:Stop()
end

local function lower2()
	if stancevalue == 1 then
		script.Parent.Holding.Value = false
		stancevalue = 0
		loadAndPlayAnim(8625656398, "ToIdle1")
	elseif stancevalue == 2 then
		script.Parent.Holding.Value = true
		stancevalue = 1
		loadAndPlayAnim(8625657640, "ToStance1")
		loadAndPlayAnim(8625647558, "Stance1")
	end
end

This does work, however the ‘Stance1’ or ‘Stance2’ animations, which consist of this, Doesn’t loop or stay in position but goes back. The ToStance animation does work.

For the full script: (Edited)

wait()
local raise = script.Parent.Raise
local lower = script.Parent.Lower
local stancevalue = script.Parent.Stance.Value
local plr = script.Parent.Parent.Name
local player = game.Players:FindFirstChild(plr)
local character = player.Character
local person = player.Character
local humanoid = character:WaitForChild("Humanoid")
local shield = script.Parent

local animation = Instance.new("Animation")
animation.Parent = script.Parent
local animtrack = nil

local function loadAndPlayAnim(animId, animName)
	animation.Name = animName
	animation.AnimationId = "rbxassetid://"..animId
	animtrack = nil
	animtrack = humanoid:LoadAnimation(animation)
	repeat
		task.wait()
	until animtrack.Length > 0.1
	animtrack:Play()
	task.wait(0.17)
	animtrack:Stop()
end

local function raise2(plr)
	if stancevalue == 0 then
		stancevalue = 1
		script.Parent.Holding.Value = true
		loadAndPlayAnim(8625649454, "ToStance1")
		loadAndPlayAnim(8625647558, "Stance1")
	elseif stancevalue == 1 then
		stancevalue = 2
		loadAndPlayAnim(8625654811, "ToStance2")
		loadAndPlayAnim(8625652836, "Stance2")
	end
end

local function lower2()
	if stancevalue == 1 then
		script.Parent.Holding.Value = false
		stancevalue = 0
		loadAndPlayAnim(8625656398, "ToIdle1")
	elseif stancevalue == 2 then
		script.Parent.Holding.Value = true
		stancevalue = 1
		loadAndPlayAnim(8625657640, "ToStance1")
		loadAndPlayAnim(8625647558, "Stance1")
	end
end


raise.OnServerEvent:Connect(raise2)
lower.OnServerEvent:Connect(lower2)

Yes, as a single “Animation” instance is being used, each time an animation is loaded the previous one is stopped, if you need animations to play out in full then instead of waiting/delaying for an arbitrary length of time (0.17 seconds) listen for the “.Stopped” event to fire each time an AnimationTrack instance is played.

local function loadAndPlayAnim(animId, animName)
	animation.Name = animName
	animation.AnimationId = "rbxassetid://"..animId
	animtrack = nil
	animtrack = humanoid:LoadAnimation(animation)
	repeat
		task.wait()
	until animtrack.Length > 0
	animtrack:Play()
	animtrack.Stopped:Wait()
	animtrack:Stop()
end

Also I’m not sure what you’re trying to convey with the provided image.

I don’t know how the function is running if its on loop or nah. but i assume you should set

stancevalue = 1 --or 2

after the animation stops

That only works for the ‘ToStance’ animations, How do I make the Stance animations loop? (I want the stance animation to loop or ‘hold’ in place)

With that implementation all of the animations will play out in full once (it works).

In the scripts you have provided there has been no effort made to loop any of the animations, if you need an animation to loop then you should call the instance method “:Play()” on the AnimationTrack instance for however many times the animation should loop for, similarly you can enable the “Looped” property of the AnimationTrack instance such that it loops and then disable it when necessary.

I have no idea of what the purpose of “stancevalue”, “Holding.Value” is but make sure they are being set correctly.

local function loadAndPlayAnim(animId, animName, doLoop)
	animation.Name = animName
	animation.AnimationId = "rbxassetid://"..animId
	animtrack = nil
	animtrack = humanoid:LoadAnimation(animation)
	repeat
		task.wait()
	until animtrack.Length > 0
	animtrack.Looped = doLoop
	animtrack:Play()
	animtrack.Stopped:Wait()
	animtrack:Stop()
end

loadAndPlayAnim(8625652836, "Stance2", false) --false here indicates that the animation shouldnt loop (should only play out once)
loadAndPlayAnim(8625652836, "Stance2", true) --true here indicates the the animation should loop (play out multiple times until a new animation is requested)

Here’s an example of how you could achieve animation looping.

If you need animations to resume from where they were stopped then this will require an entirely new implementation.