How to make sure no other animations are playing

I’m trying to make an emote script. When a button is pressed, an emote should play, and when pressed again, it should stop playing. That works fine. The problem I’m having is that I need to detect if any OTHER animations are playing, and if so, then to not play this one.

I’ll try to keep it short but I need a lot of detail and I’m going insane trying to figure this out:
Basically, there are seats around the game that when sat on use this code to play an animation on the player:
(Serverside script)

seat1 = script.Parent
function added(child)
	if (child.className=="Weld") then
		local human = child.part1.Parent:FindFirstChild("Humanoid")
		if human ~= nil then
			anim = human:LoadAnimation(seat1.sitanim)
			anim:Play()
		end
	end
end

function removed(child2)
	if anim ~= nil then
		local human = child2.part1.Parent:FindFirstChild("Humanoid")
		anim:Stop()
		anim:Remove()
	end
end

seat1.ChildAdded:connect(added)
seat1.ChildRemoved:connect(removed)

Now, whenever you sit on one of the seats and the animation for it plays, you can still use the emotes and it overrides the seat’s animation, which I don’t want it to.
The second problem is the opposite way around, where you use the emote on top of the seat so that a few seconds after using the emote you sit down. Doing this stops you from ever leaving the seat by jumping.

And here’s the emote code:
(local script, also there is more after but it’s the same functions with different buttons)

local EmotesFrame = script.Parent
local innerFrame = EmotesFrame.InnerFrame
local innerFrame2 = innerFrame.Frame
local Input = game:GetService("UserInputService")
local module = require(game.ReplicatedStorage.Variables)
local player = game.Players.LocalPlayer
local human = player.Character:WaitForChild("Humanoid")
module.animated = false

innerFrame.Back.MouseButton1Click:Connect(function()
	EmotesFrame.Visible = false
end)

player.CharacterAdded:Connect(function()
	module.animated = false
end)



innerFrame2.Sit.MouseButton1Click:Connect(function()
	local human = player.Character:WaitForChild("Humanoid")
		if module.animated == false then
			local human = player.Character:WaitForChild("Humanoid")
			local anim = innerFrame2.Sit.Animation
			human.WalkSpeed = 0
			human.JumpPower = 0
			game.ReplicatedStorage.Animation:FireServer(anim, module.animated)
			module.animated = true
		else
			local human = player.Character:WaitForChild("Humanoid")
			local anim = innerFrame2.Sit.Animation
			human.WalkSpeed = 16
			human.JumpPower = 50
			game.ReplicatedStorage.Animation:FireServer(anim, module.animated)
			module.animated = false
	end
end)

And probably not needed, but the second part of the emote code that’s serverside so other players see:

game.ReplicatedStorage.Animation.OnServerEvent:Connect(function(player, animation, animated)
	local anim
	if animated == false then
	 	local character = player.Character
		local human = character:WaitForChild("Humanoid")
		anim = human:LoadAnimation(animation)
		anim:Play()
	else
		local character = player.Character
		local human = character:WaitForChild("Humanoid")
		for _,thisTrack in pairs (human.Animator:GetPlayingAnimationTracks()) do
			thisTrack:Stop()
		end
	end
end)

I’m probably asking for too much with this, but I literally cannot find any way to do this and I’ve been trying really hard to find a solution. I did use attributes on the humanoid at one point to solve the first problem, but it didn’t solve the second and also I didn’t trust its reliability so I removed it.

If you are happy to switch your animation loading to the animator instance, you can detect if any other animations are playing by using the GetPlayingAnimationTracks method.

For this, wouldn’t I have to manually check every single possible animation that could be playing? Or am I misunderstanding?

It returns an array which you can then check to see if either; one or more animations are playing, using:

if animator:GetPlayingAnimationTracks() >= 1 then
     return true #there are one or more tracks playing
else

or check to see if a specific animation track is playing;
when you call GetPlayingAnimationTracks it returns an array with every animation object that is playing for example if you load the animation game.Workspace.TestAnimation onto the animator then play it, when you call GetPlayingAnimationTracks it will return an array with the TestAnimation object.

Example:

local animation = script.Animation
local character = game.Workspace.Rig

local humanoid = character:FindFirstChildOfClass("Humanoid")
local animator = humanoid and humanoid:FindFirstChildOfClass("Animator")

if not animator then
	warn("Animator not found.")
	return
end

warn("No animations currently playing:")

print(animator:GetPlayingAnimationTracks())

coroutine.wrap(function()
	wait(10)
	warn("Starting to play animation...")

	local animationTrack = animator:LoadAnimation(animation)
	animationTrack.Looped = true
	animationTrack:Play()
end)()

local function isAnimationPlaying()
	return #animator:GetPlayingAnimationTracks() > 0
end

while wait(1) do
	if isAnimationPlaying() then
		warn("One or more animations are playing!")
		print(animator:GetPlayingAnimationTracks())
	else
		print("No animations playing")
	end
end

Output:


Rig Example:
image

1 Like

Thank you for the help, but in the end I managed to get it working through a very questionable method that I might regret later- but at least from my testing it seems to work. (basically used a remote event that gets called whenever they sit or un-sit to change a few variables)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.