GetTimeOfKeyframe working improperly - "Invalid operation for this animation format."

I would like to be able to find the time position of a certain keyframe (marker) event in an animation

The keyframe is properly named and present, however when I run the function it errors “Invalid operation for this animation format.”

I have looked all over, but many claim to wait for it to load. I have checked, and the animation is loaded and that would make sense as this function takes place after ~10s of when the tracks are loaded

The animations are made with the graph editor, and I have found that that could be the issue? Is there any workaround if that is the case, is there anyway to obtain all animation events in a track, such that I could put all events into a lookup table?

Here is the function:

function Animations.SafeTimeOfKeyframe(Track : AnimationTrack, KeyframeName) : number?

    local Time;

    local s, e = pcall(function()
        Time = Track:GetTimeOfKeyframe(KeyframeName)
    end)

    print(s, e)

    return Time
    
end

And here is how it is used in another function:


-- Binds a function to a keyframe being reached. Returns if a keyframe has the valid name
function Animations.BindToKeyframeReached(Key : string, AnimationManager : Types.AnimationManager, KeyframeName : string, Callback : () -> (), Once:boolean) : boolean

    local Track = AnimationManager.Tracks[Key]
    local Connections = {}
    local KeyFrameFound = false;

    local function SetupTrack(FoundTrack : AnimationTrack)

        local KeyframeTime = Animations.SafeTimeOfKeyframe(FoundTrack, KeyframeName)
        if not KeyframeTime then return end

        KeyFrameFound = true;

        table.insert(Connections, FoundTrack:GetMarkerReachedSignal(KeyframeName):Connect(function()
            
            Callback()
            if not Once then return end
            for i, v in Connections do
                
                v:Disconnect()

            end

        end))
        
    end

    if type(Track) == "table" then
        for _, track : AnimationTrack in Track do
            SetupTrack(track)
        end
    else
        SetupTrack(Track)
    end

    return KeyFrameFound
    
end

Any help is greatly appreciated, thanks for reading.

Nevermind, for anyone searching for a similar problem, here’s what I did:

I used KeyframeSequenceProvider to get the keyframe sequence. Despite it being depricated, no matter how much I searched, the new animationClip class does not contain markers and does not work for my use case, and there was no other workaround

Heres what I did, due to :GetKeyFrameSequenceAsync(AssetId) Being slow on my curve editor animations, I stored them in the animation manager object I am using

local KS : KeyframeSequence = KeyframeSequenceProvider:GetKeyframeSequenceAsync(Id)

AnimationManager.TrackEvents[Key] = {}

for i, v in KS:GetKeyframes() do
    
    local Markers = v:GetMarkers()
    for _, Marker in Markers do

        AnimationManager.TrackEvents[Key][Marker.Name] = v.Time

    end

end

AnimationManager.Loaded[Key] = true;

This way I can bind to any event like this:

local KeyframeTime = AnimationManager.TrackEvents[Key][KeyframeName]
if not KeyframeTime then return end

KeyFrameFound = true;

FoundTrack:GetMarkerReachedSignal(KeyframeName):Connect(function()
            
      Callback()

end)

And get my original use of knowing whether it had binded to something or not at all

1 Like

I’m having this issue as well; GetMarkerReachedSignal simply does not fire for some animation ids even when they’re clearly marked on the timeline in the animation editor as an Animation Event.