Converting old keyframes to Markers

As the title says. I have a lot of animations that use the old keyframes (so they work with KeyframeReached) but I found that the new KeyframeMarkers are pretty great too.

Only thing is, KeyframeReached doesn’t work with Markers (or last I saw it didn’t). Is there a reliable way to convert my animations to work with the new GetMarkerReachedSignal, or even better, make Markers work with KeyframeReached? It’s going to be a pain trying to convert everything so I’m hoping there is an easier way.

If I’m not mistaken, aren’t markers just an additional component of Keyframes?
https://developer.roblox.com/en-us/api-reference/function/Keyframe/AddMarker

Markers and named keyframes aren’t interchangeable. KeyframeReached is only good for named keyframes and GetMarkerReachedSignal will only fire off for a reached marker. You will not be able to do this without putting in some hard, manual labour - especially if you have many animations and/or keyframes to be changing.

The obvious way to convert is to import your animations via the Animation Editor one by one and use the editor to add markers to named keyframes.

The second way works best with Moon Animation Suite. If you are familiar with MAS (specifically the old version, I don’t have anything for the new) it will export the animation you have created into a KeyframeSequence that you can break down in the workspace. Through this you’ll be able to find your named keyframes as the immediate children of the exported sequence.

The default name of a keyframe, as far as I know from any animation editor, is simply “Keyframe”. Using the above method, we can then instance a KeyframeMarker which represents a marker, then AddMarker on a named keyframe to put the marker on the keyframe. You can reset the keyframe’s name here if you want to just “keyframe”, but for backwards compatibility reasons, best not to.

for _, keyframe in ipairs(exportedSequenceObject:GetChildren()) do
    if not (keyframe.Name == "Keyframe") then
        local marker = Instance.new("KeyframeMarker")
        marker.Name = keyframe.Name
        -- Parenting it straight is fine too, AddMarker is for convenience and
        -- being clear in why you're putting a marker in a keyframe.
        keyframe:AddMarker(marker)
    end
end

The above method still requires you to import all animations, break them down into a format that allows you to see their composition in the DataModel, then export them accordingly. You see, while you can automate a part of this, you still can’t get away without breaking your back to do this.

If you ask me, the second option sounds inviting but is much more arduous than the first. That is, unless you also save copies of the exported sequences, which gets rid of a lot of barriers easily and then makes it much more viable than the first.

1 Like

I expected some work so it’s alright if I lose a leg or two doing this. I use only MAS and Blender so this is actually the best case scenario. I assume by doing this way, the markers should still be in the same time slot. If this is true, then it’s all I needed.

Thanks. Time to get a cup of coffee and some bread, today’s going to be a long night.

1 Like

Absolutely.

Markers are independent instances, so they’re independent of time and anything related to a keyframe. The way that GetMarkerReachedSignal is that essentially when a keyframe passes that has a marker instance in it, it will fire off a reached signal. This is what the developer gets on their end, being able to connect to when a specific marker is reached.

For MAS and Blender-imported animations, that is definitely the best case scenario because those will offer you the decomposition of the sequences in the DataModel. So long as you have them saved around, it’s just a long while of inserting, converting and then reuploading. That’s already half the work being cut out.

1 Like