KeyframeSequence
This object stores all the Keyframes for an animation, determines if the animation is looped, and determines its priority against other animations.
What is a KeyframeSequence?
Roblox constructs the animation data it uses in the playback of an animation, referenced by the Animation.AnimationId property from a KeyframeSequence. Every animation refers to a KeyframeSequence or to a CurveAnimation internally. Although, usually created by the Roblox Animation Editor, KeyframeSequence can also be created by other plugins or even manually. Once uploaded to Roblox, Roblox assigns a Content ID that Animations use for the Animation.AnimationId property to refer to the uploaded KeyframeSequence.
Note, in most cases, you do not need to manipulate KeyframeSequences, as the animation editor covers most animation functionality. However, in some cases you may wish to generate an animation from a Script or build your own plugin. However, only Roblox Studio can use a KeyframeSequence created in such a way. If you wish to use such a KeyframeSequence, you will need to upload it to Roblox as described below.
KeyframeSequence Properties
KeyframeSequence.Priority and KeyframeSequence.Loop save the priority and looped animation settings for the sequence. Note that AnimationTrack properties can eventually overwrite these properties at playback time.
The last Keyframe in the sequence, meaning the Keyframe with the highest Keyframe.Time property, determines the length of an animation.
KeyframeSequence Structure
KeyframeSequences act as a container that hold Keyframes. Keyframes represent a 'key' frame in the animation, that are interpolated between during playback.
Keyframes contain Poses. Poses, specific to each BasePart being animated, contain the CFrame applied to the Motor6D connecting two parts. Poses match the BasePart they correspond with by name and apply their data to the Motor6D with this same-named part identified as Motor6D.P1 . For this reason, animations require distinct part names to play correctly.
Poses follow a structure based on joint hierarchy. The parent of each Pose corresponds to the Pose of the part it is attached to. In practice, this means the poses branch out from the root part. See below for a visual example.
Using KeyframeSequences when making animations
You must first upload KeyframeSequences to Roblox before they can be played in an experience. In Studio, right click on the KeyframeSequence and click 'Save to Roblox'. Alternatively, you can use the Plugin:SaveSelectedToRoblox() function. Either method will bring up the animation upload window and allow you to upload your KeyframeSequence as an animation.
In some cases, you may want to preview an Animation before uploading it to the Roblox site. You can generate a temporary id using KeyframeSequenceProvider:RegisterKeyframeSequence(). This will generate a hash id that can be used for localized animation testing.
Obtaining KeyframeSequences
In some cases you may wish to download the KeyframeSequence corresponding to an existing uploaded Animation. You can use AnimationClipProvider:GetAnimationClipAsync() to download an animation.
Code Samples
local function getSequenceLength(keyframeSequence)
local length = 0
for _, keyframe in pairs(keyframeSequence:GetKeyframes()) do
if keyframe.Time > length then
length = keyframe.Time
end
end
return length
end
local keyframeSequence = Instance.new("KeyframeSequence")
getSequenceLength(keyframeSequence)
local KeyframeSequenceProvider = game:GetService("KeyframeSequenceProvider")
local function createPreviewAnimation(keyframeSequence)
local hashId = KeyframeSequenceProvider:RegisterKeyframeSequence(keyframeSequence)
local Animation = Instance.new("Animation")
Animation.AnimationId = hashId
return Animation
end
local keyframeSequence = Instance.new("KeyframeSequence")
local animation = createPreviewAnimation(keyframeSequence)
print(animation)
-- create the keyframesequence
local keyframeSequence = Instance.new("KeyframeSequence")
keyframeSequence.Loop = false
keyframeSequence.Priority = Enum.AnimationPriority.Action
-- create a keyframe
local keyframe = Instance.new("Keyframe")
keyframe.Time = 0
-- create sample poses
local rootPose = Instance.new("Pose")
rootPose.Name = "HumanoidRootPart"
rootPose.Weight = 0
local lowerTorsoPose = Instance.new("Pose")
lowerTorsoPose.Name = "LowerTorso"
lowerTorsoPose.Weight = 1
-- set the sequence hierarchy
rootPose:AddSubPose(lowerTorsoPose) -- lowerTorsoPose.Parent = rootPose
keyframe:AddPose(rootPose) -- rootPose.Parent = keyframe
keyframeSequence:AddKeyframe(keyframe) -- keyframe.Parent = keyframeSequence
-- parent the sequence
keyframeSequence.Parent = workspace
Summary
Properties
Contains the hip height of the Humanoid of the model that was used to author this KeyframeSequence.
Determines whether the animation stored in this AnimationClip is intended to loop.
Determines which clip takes priority when multiple animations are playing simultaneously.
Methods
Adds a Keyframe to the KeyframeSequence by parenting it to the KeyframeSequence.
Returns an array that contains all Keyframes contained in a KeyframeSequence.
This function removes a Keyframe from the KeyframeSequence by setting its parent to nil.
Properties
AuthoredHipHeight
Contains the hip height of the Humanoid of the model that was used to author this KeyframeSequence. Default value is 1.35 since that is the hip height set for a standard R15 Character|character.
Methods
AddKeyframe
This function adds a Keyframe to the KeyframeSequence by parenting it to the KeyframeSequence. It is functionally identical to setting the keyframe's Instance.Parent to the KeyframeSequence.
Note, this function will not error when called with an instance other than a Keyframe as the keyframe parameter and will parent it successfully.
Parameters
Returns
Code Samples
-- create the keyframesequence
local keyframeSequence = Instance.new("KeyframeSequence")
keyframeSequence.Loop = false
keyframeSequence.Priority = Enum.AnimationPriority.Action
-- create a keyframe
local keyframe = Instance.new("Keyframe")
keyframe.Time = 0
-- create sample poses
local rootPose = Instance.new("Pose")
rootPose.Name = "HumanoidRootPart"
rootPose.Weight = 0
local lowerTorsoPose = Instance.new("Pose")
lowerTorsoPose.Name = "LowerTorso"
lowerTorsoPose.Weight = 1
-- set the sequence hierarchy
rootPose:AddSubPose(lowerTorsoPose) -- lowerTorsoPose.Parent = rootPose
keyframe:AddPose(rootPose) -- rootPose.Parent = keyframe
keyframeSequence:AddKeyframe(keyframe) -- keyframe.Parent = keyframeSequence
-- parent the sequence
keyframeSequence.Parent = workspace
GetKeyframes
GetKeyframes returns an array that contains all Keyframes that have been added to a KeyframeSequence.
Returns
An array of Keyframe.
Code Samples
local function getSequenceLength(keyframeSequence)
local length = 0
for _, keyframe in pairs(keyframeSequence:GetKeyframes()) do
if keyframe.Time > length then
length = keyframe.Time
end
end
return length
end
local keyframeSequence = Instance.new("KeyframeSequence")
getSequenceLength(keyframeSequence)
RemoveKeyframe
This function removes a Keyframe from the KeyframeSequence by setting its parent to nil. It is functionally identical to setting the keyframe's parent to nil.
This sets the keyframe's parent to nil, but does not destroy it. This means, provided another reference to the keyframe remains, it can be re-parented later.
Note, this function will not error when called with an Instance other than a Keyframe as the keyframe parameter.
Parameters
Returns
Code Samples
local keyframeSequence = Instance.new("KeyframeSequence")
keyframeSequence.Parent = workspace
local keyframe = Instance.new("Keyframe")
keyframeSequence:AddKeyframe(keyframe)
task.wait(2)
keyframeSequence:AddKeyframe(keyframe)