Something's wrong with AnimationClipProvider:GetAnimationClipAsync

Hey! So, I’m making an animations module for personal use as it’d be helpful for some stuff. However, I have a function there that gets all the event names for an animation, but for some reason, when I attempt calling AnimationClipProvider:GetAnimationClipAsync it just returns an empty KeyframeSequence.

On a side note, when performing the function outside testing mode, it returns a normal KeyframeSequence with Keyframes, KeyframeMarkers, etc. is anyone going through the same issue? I’ve been struggling to make it work.

1 Like

When using AnimationClipProvider:GetAnimationClipAsync(AnimId)
image

When using KeyframeSequenceProvider:GetKeyframeSequenceAsync(AnimId)
image

2 Likes

Seems to be a problem with new animations specifically.

1 Like

Having the same issue. I discovered that loading the animation before requesting its keyframe data with GetAnimationClipAsync makes all calls to this function return an empty KeyframeSequence.

KeyframeSequenceProvider doesn’t have this problem, but in my game it stops working after downloading the animation for the first time. It could be related to this bug report.

There are two possible workarounds:

  • downloading & caching the data from the keyframe sequence before loading the animation;
  • using KeyframeSequenceProvider with a session cache.

I’ll make a bug report regarding this issue. It’ll take some time because I’m not allowed to post directly in #bug-reports.

EDIT:

Fixed the issue by calling GetAnimationClipAsync again after it returns an empty KeyframeSequence. Just in case, add a max amount of retries and that’s it. I’m not going to bother making a bug report.

GetKeyframeSequenceAsync has similar results:

EDIT 2:

I was still having issues in my game, so I just decided to cache the result of GetKeyframeSequenceAsync because it works the first time it’s called.

Here’s the module if anyone needs it:

local KeyframeSequenceProvider = game:GetService("KeyframeSequenceProvider")

local anim_data = {}
anim_data.cache = {}

function anim_data._fetchKeyframeData(id: string): KeyframeSequence?
  local success, response = pcall(function()
    return KeyframeSequenceProvider:GetKeyframeSequenceAsync(id)
  end)

  if not success then
    warn(`failed to fetch keyframe sequence for '{id}':\n{response}`)
    return
  end

  return response
end

function anim_data._getAll(id: string)
  local seq = anim_data._fetchKeyframeData(id)

  if not seq then
    return {
      events = {},
      length = 0,
    }
  end

  local events = {}
  local length = 0

  for _, desc in seq:GetDescendants() do
    if desc:IsA("KeyframeMarker") then
      local keyframe = desc:FindFirstAncestorOfClass("Keyframe")

      table.insert(events, {
        time = keyframe and keyframe.Time or 0,
        name = desc.Name,
        value = desc.Value,
      })
    elseif desc:IsA("Keyframe") and desc.Time > length then
      length = desc.Time
    end
  end

  seq:Destroy()

  table.sort(events, function(a, b)
    return a.time < b.time
  end)

  return {
    events = events,
    length = length,
  }
end

function anim_data.getAnimationEvents(id: string)
  local data = anim_data.cache[id]

  if not data then
    data = anim_data._getAll(id)
    anim_data.cache[id] = data
  end

  return data.events
end

function anim_data.getAnimationLength(id: string)
  local data = anim_data.cache[id]

  if not data then
    data = anim_data._getAll(id)
    anim_data.cache[id] = data
  end

  return data.length
end

return anim_data

That makes sense. I’ve tried caching and doing the requests again, but it returns an empty KeyframeSequence anyway. I’m not sure why the deprecated Keyframe service does work well for me while the new service just returns an empty instance.