Statically retrieve animation lengths

As a Roblox developer, it is currently impossible to know the absolute length of an animation without first loading it into a humanoid.

This is extra frustrating, because the length attribute of the animationtrack is initially set to 0, but the humanoid:LoadAnimation() call doesn’t yield, meaning that it is possible to read off the incorrect value of animation length. Also, we have no way of knowing whether an animation track has actually loaded, meaning we have to rely on a hack (checking if length > 0 or not) to make it work.

This isn’t very clear in the documentation, and can lead to a lot of frustrating moments while loading animations. (ex: this thread How can I know when an AnimationTrack is loaded?, where a user is confused about animationtracks and their loading behavior).

There should be some way to retrieve animation lengths without having to load the entire animation first (or atleast some better behavior with respect to yielding).

4 Likes

In the meantime, here’s a (less hacky) method you can use with better yielding behavior than what you described:

local Provider = game:GetService("KeyframeSequenceProvider")
local Cache = {}

local function GetAnimationLength(Animation)
	local AssetId = Animation.AnimationId
	if Cache[AssetId] then
		return Cache[AssetId]
	end

	local Sequence = Provider:GetKeyframeSequenceAsync(AssetId)
	local Keyframes = Sequence:GetKeyframes()
	
	local Length = 0
	for i = 1, #Keyframes do
		local Time = Keyframes[i].Time
		if Time > Length then
			Length = Time
		end
	end
	
	Sequence:Destroy()
	Cache[AssetId] = Length
	
	return Length
end
2 Likes