Are Animation Events unreliable?

When scripting my newest game, I made most of the attacks function with Animation Events to keep everything in sync. Most of the time, it works perfectly fine! For example, you press the button, your character makes themselves invincible for the duration of the animation, they finish the attack and boom! They make you vulnerable again to allow you to continue playing normally.

But sometimes, the animations fail to load, causing serious issues.

You press the button, your character makes themselves invincible, animation fails to play and you’re stuck with invincibility.

This seems like an easy fix, just remove invincibility after a few seconds or something but this is just a simple example. There are very complicated issues that comes with this issue that will take days to fix. I’d be completely okay with spending weeks to fix this, but it isn’t even a proper “fix” which is very annoying.

I wish I knew it functioned like this so I could take another route but sadly I just read “fires at a certain point of animation!” and went “Oooh! This is exactly what I’m looking for!”

It sucks that we can’t get around this with preload aswell since apparently roblox doesn’t allow you to reload an asset after it failed once.

I don’t have much hope at this point and will probably have to continue with the current system but please let me know if you have a way to work around this…

1 Like

How are you playing the animations?

Preload them on the animator, and save them for later use.

I have a script that copies all animations in the game, pastes them into a folder in ReplicatedFirst and then a local script (which is also in replicated first) preloads them with this:

repeat
	wait()
until script.Done.Value == true
local CP = game:GetService("ContentProvider")
local Animations = script:WaitForChild("Animations")

CP:PreloadAsync(Animations:GetChildren())

(The script sets “Done” to true after pasting all animations in the folder)

There’s also this which rarely fails:

--loads and plays animation
used = false
local Humanoid = script.Parent.Parent.Parent.ObjectHumanoid
local Move = script.Move
local MoveAnim = Humanoid.Animator:LoadAnimation(Move)
local Idle = script.Idle
local IdleAnim = Humanoid.Animator:LoadAnimation(Idle)
IdleAnim:Play()
--makes the box visible
for i = 1,10 do
	task.wait(0.05)
	script.Parent.Parent.Transparency = script.Parent.Parent.Transparency - 0.1
end
--stops idle animation and plays opening animation
script.Parent.Triggered:Connect(function(player)
	if player.Character:FindFirstChildOfClass("Humanoid") ~= nil and used == false then
		used = true
		script.Parent.Enabled = false
		IdleAnim:Stop()
		MoveAnim:Play()
		script.Parent.Parent.Lock:Play()
	end
end)
--detects when the opening animation ends, freezes the animation and makes it disappear
MoveAnim:GetMarkerReachedSignal("Ended"):Connect(function()
	MoveAnim:AdjustSpeed(0)
	for i = 1,10 do
		task.wait(0.05)
		script.Parent.Parent.Transparency = script.Parent.Parent.Transparency + 0.1
	end
	script.Parent.Parent.Parent:Destroy()
end)

It’s a box with a single script in it (The script is inside a Proximity Prompt). On very rare occasions, the box does not disappear, which means the Animation is not playing.

When this box thing happens, it happens to every single box in the entire server, which is odd.

Have you tried print statements to determine what runs and what doesn’t?
No errors in output?

Do note that animator:LoadAnimation() throws an error if the animator isn’t in workspace.

Sadly, this never happened to me. It is from my new game that released about a week ago and only a few people reported it. I tried my best to get it to happen to me but nope.

Joined with an old laggy phone, used bad internet, tried to make it happen in studio by editing code, joining random servers for hours but nope. I’m still trying though.

The only thing I know is it only happens with scripts that work with animation events or things that have something to do with animations like “AnimationTrack.Stopped”.

It can range from a box not disappearing to a player being invincible forever. I can’t let it slip just because it’s rare :confused:

Alright, the animation loading error I’m talking about is ‘Cannot load the AnimationClipProviderService’

Might be worth it to look for that error in the analytics.

But it could be something entirely different.

1 Like

Maybe try using pcall()?
Any error inside a protected call function will not be propagated, instead it will catch the error and return the status code. This will not halt the execution of the code!

local success, err = pcall(function() -- will catch errors and not halt the execution of code
   track:Play()
   -- or loading the animation
end)
if not success then print(err) end -- if it made an error, like the animation load error, print the error
-- code under this code will still be executed
1 Like

I remember seeing that error once on the client even though the game was playing smoothly without any problems. I was just checking the output.

The script I sent about the box is entirely on server side, so I assume that error wouldn’t happen? I also think so because can’t see any mention of AnimationClipProviderService on error reports analytics oof

I assume this will allow me to see it on error reports analytics so maybe this’ll help! Thanks!

Update, I managed to find exactly what you said in error reports!

Assuming this is the reason, how would I fix this If we base it off of the box script I sent?

That error happens if the animator isn’t in the workspace by the time you call ‘LoadAnimation’.

What I did is to try a couple times to load the animation (using pcall), and wait some time in between them. If it fails after a couple tries (and a couple seconds), just don’t setup.

Depends on what the code is for though, but for my usecase it was playing emotes on the character, so I could get away with just cancelling the script.

2 Likes