AnimationTrack

Show Deprecated
not creatable

Controls the playback of an animation on a Humanoid or AnimationController. This object cannot be created, instead it is returned by the Humanoid:LoadAnimation() method.

Code Samples

Animation Creation

local Players = game:GetService("Players")
local player = Players:FindFirstChild("Builderman")
local character = player.Character
local humanoid = character:FindFirstChild("Humanoid")
local animation = Instance.new("Animation")
animation.AnimationId = "http://www.roblox.com/asset/?id=507771019" -- Roblox dance emote
local animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()

Summary

Properties

  • read only
    not replicated
    read parallel

    The Animation object that was used to create this AnimationTrack.

  • read only
    not replicated
    read parallel

    A read only property that returns true when the AnimationTrack is playing.

  • read only
    not replicated
    read parallel

    A read only property that returns the length (in seconds) of an AnimationTrack. This will return 0 until the animation has fully loaded and thus may not be immediately available.

  • read parallel

    Sets whether the animation will repeat after finishing. If it is changed while playing the result will take effect after the animation finishes.

  • Sets the priority of an AnimationTrack. Depending on what this is set to, playing multiple animations at once will look to this property to figure out which Keyframe Poses should be played over one another.

  • read only
    not replicated
    read parallel

    The Speed of an AnimationTrack is a read only property that gives the current playback speed of the AnimationTrack. This has a default value of 1. When speed is equal to 1, the amount of time an animation takes to complete is equal to AnimationTrack.Length (in seconds).

  • not replicated
    read parallel

    Returns the position in time in seconds that an AnimationTrack is through playing its source animation. Can be set to make the track jump to a specific moment in the animation.

  • read only
    not replicated
    read parallel

    Read-only property that gives the current weight of the AnimationTrack. It has a default value of 1.

  • read only
    not replicated
    read parallel

    Read-only property that gives the current weight of the AnimationTrack.

Methods

Events

Properties

Animation

read only
not replicated
read parallel

The Animation object that was used to create this AnimationTrack. To create an AnimationTrack the developer must load an Animation object onto a Humanoid or AnimationController using the Humanoid:LoadAnimation() method.

The Animation property is used to identify the underlying Animation of an AnimationTrack.

Code Samples

Listen For New Animations

local function listenForNewAnimations(humanoid)
humanoid.AnimationPlayed:Connect(function(animationTrack)
local animationName = animationTrack.Animation.Name
print("Animation playing " .. animationName)
end)
end
local humanoid = script.Parent:WaitForChild("Humanoid")
listenForNewAnimations(humanoid)

IsPlaying

read only
not replicated
read parallel

A read only property that returns true when the AnimationTrack is playing.

This property can be used by developers to check if an animation is already playing before playing it (as that would cause it to restart). If a developer wishes to obtain all playing AnimationTracks on a Humanoid or AnimationController they should use Humanoid:GetPlayingAnimationTracks()

Code Samples

AnimationTrack IsPlaying

local function playOrAdjust(animationTrack, fadeTime, weight, speed)
if not animationTrack.IsPlaying then
animationTrack:Play(fadeTime, weight, speed)
else
animationTrack:AdjustSpeed(speed)
animationTrack:AdjustWeight(weight, fadeTime)
end
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
playOrAdjust(animationTrack, 1, 0.6, 1)

Length

read only
not replicated
read parallel

A read only property that returns the length (in seconds) of an AnimationTrack. This will return 0 until the animation has fully loaded and thus may not be immediately available.

When the AnimationTrack.Speed of an AnimationTrack is equal to 1, the animation will take AnimationTrack.Length (in seconds) to complete.

Code Samples

Playing Animation for a Specific Duration

local function playAnimationForDuration(animationTrack, duration)
local speed = animationTrack.Length / duration
animationTrack:Play()
animationTrack:AdjustSpeed(speed)
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765000"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
playAnimationForDuration(animationTrack, 3)

Looped

read parallel

This property sets whether the animation will repeat after finishing. If it is changed while playing the result will take effect after the animation finishes.

The Looped property for AnimationTrack defaults to how it was set in the animation editor. However this property can be changed, allowing control over the AnimationTrack while the game is running. Looped also correctly handles animations played in reverse (negative AnimationTrack.Speed). After the first keyframe is reached, it will restart at the last keyframe.

This property allows the developer to have a looping and non looping variant of the same animation, without needing to upload two versions to Roblox.

Code Samples

Animation Looping

local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
while not localPlayer.Character do
task.wait()
end
local character = localPlayer.Character
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507770453"
local animationTrack = animator:LoadAnimation(animation)
animationTrack.Looped = false
task.wait(3)
animationTrack:Play()
task.wait(4)
animationTrack.Looped = true
animationTrack:Play()
Play AnimationTrack for a Number of Loops

local function playForNumberLoops(animationTrack, number)
animationTrack.Looped = true
animationTrack:Play()
local numberOfLoops = 0
local connection = nil
connection = animationTrack.DidLoop:Connect(function()
numberOfLoops = numberOfLoops + 1
print("loop: ", numberOfLoops)
if numberOfLoops >= number then
animationTrack:Stop()
connection:Disconnect() -- it's important to disconnect connections when they are no longer needed
end
end)
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
playForNumberLoops(animationTrack, 5)
read parallel

This property sets the priority of an AnimationTrack. Depending on what this is set to, playing multiple animations at once will look to this property to figure out which Keyframe Poses should be played over one another.

The Priority property for AnimationTrack defaults to how it was set and published from Studio's Animation Editor. It uses the AnimationPriority Enum, which has 7 priority levels.

  1. Core (lowest priority)
  2. Idle
  3. Movement
  4. Action
  5. Action2
  6. Action3
  7. Action4 (highest priority)

Correctly set animation priorities, either through the editor or through this property allow multiple animations to be played without them clashing. Where two playing animations direct the target to move the same limb in different ways, the AnimationTrack with the highest priority will show. If both animations have the same priority, the weights of the tracks will be used to combine the animations.

This property also allows the developer to play the same animation at different priorities, without needing to upload additional versions to Roblox.

Speed

read only
not replicated
read parallel

The Speed of an AnimationTrack is a read only property that gives the current playback speed of the AnimationTrack. This has a default value of 1. When speed is equal to 1, the amount of time an animation takes to complete is equal to AnimationTrack.Length (in seconds).

If the speed is adjusted, then the actual time it will take a track to play can be computed by dividing the length by the speed. Speed is a unitless quantity.

Speed can be used to link the length of an animation to different game events (for example recharging an ability) without having to upload different variants of the same animation.

This property is read only, and you can change it using AnimationTrack:AdjustSpeed().

Code Samples

Animation Speed

local ContentProvider = game:GetService("ContentProvider")
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
while not localPlayer.Character do
task.wait()
end
local character = localPlayer.Character
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507770453"
ContentProvider:PreloadAsync({ animation })
local animationTrack = animator:LoadAnimation(animation)
local normalSpeedTime = animationTrack.Length / animationTrack.Speed
animationTrack:AdjustSpeed(3)
local fastSpeedTime = animationTrack.Length / animationTrack.Speed
print("At normal speed the animation will play for", normalSpeedTime, "seconds")
print("At 3x speed the animation will play for", fastSpeedTime, "seconds")
Playing Animation for a Specific Duration

local function playAnimationForDuration(animationTrack, duration)
local speed = animationTrack.Length / duration
animationTrack:Play()
animationTrack:AdjustSpeed(speed)
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765000"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
playAnimationForDuration(animationTrack, 3)

TimePosition

not replicated
read parallel

Returns the position in time in seconds that an AnimationTrack is through playing its source animation. Can be set to make the track jump to a specific moment in the animation.

TimePosition can be set to go to a specific point in the animation, but the AnimationTrack must be playing to do so. It can also be used in combination with AnimationTrack:AdjustSpeed() to freeze the animation at a desired point (by setting speed to 0).

Code Samples

Freeze Animation at Position

function freezeAnimationAtTime(animationTrack, timePosition)
if not animationTrack.IsPlaying then
-- Play the animation if it is not playing
animationTrack:Play()
end
-- Set the speed to 0 to freeze the animation
animationTrack:AdjustSpeed(0)
-- Jump to the desired TimePosition
animationTrack.TimePosition = timePosition
end
function freezeAnimationAtPercent(animationTrack, percentagePosition)
if not animationTrack.IsPlaying then
-- Play the animation if it is not playing
animationTrack:Play()
end
-- Set the speed to 0 to freeze the animation
animationTrack:AdjustSpeed(0)
-- Jump to the desired TimePosition
animationTrack.TimePosition = (percentagePosition / 100) * animationTrack.Length
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
freezeAnimationAtTime(animationTrack, 0.5)
freezeAnimationAtPercent(animationTrack, 50)

WeightCurrent

read only
not replicated
read parallel

When weight is set in an AnimationTrack it does not change instantaneously but moves from WeightCurrent to AnimationTrack.WeightTarget. The time it takes to do this is determined by the fadeTime parameter given when the animation is played, or the weight is adjusted.

WeightCurrent can be checked against AnimationTrack.WeightTarget to see if the desired weight has been reached. Note that these values should not be checked for equality with the == operator, as both of these values are floats. To see if WeightCurrent has reached the target weight, it is recommended to see if the distance between those values is sufficiently small (see code sample below).

The animation weighting system is used to determine how AnimationTracks playing at the same priority are blended together. The default weight is one, and no movement will be visible on an AnimationTrack with a weight of zero. The pose that is shown at any point in time is determined by the weighted average of all the Poses and the WeightCurrent of each AnimationTrack. In most cases blending animations is not required and using AnimationTrack.Priority is more suitable.

Code Samples

WeightCurrent and WeightTarget

local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
while not localPlayer.Character do
task.wait()
end
local character = localPlayer.Character
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animation1 = Instance.new("Animation")
animation1.AnimationId = "rbxassetid://507770453"
local animation2 = Instance.new("Animation")
animation2.AnimationId = "rbxassetid://507771019"
task.wait(3) -- arbitrary wait time to allow the character to fall into place
local animationTrack1 = animator:LoadAnimation(animation1)
local animationTrack2 = animator:LoadAnimation(animation2)
animationTrack1.Priority = Enum.AnimationPriority.Movement
animationTrack2.Priority = Enum.AnimationPriority.Action
animationTrack1:Play(0.1, 5, 1)
animationTrack2:Play(10, 3, 1)
local done = false
while not done and task.wait(0.1) do
if math.abs(animationTrack2.WeightCurrent - animationTrack2.WeightTarget) < 0.001 then
print("got there")
done = true
end
end

WeightTarget

read only
not replicated
read parallel

AnimationTrack.WeightTarget is a read-only property that gives the current weight of the AnimationTrack. It has a default value of 1 and is set when AnimationTrack:Play(), AnimationTrack:Stop() or AnimationTrack:AdjustWeight() is called. When weight is set in an AnimationTrack it does not change instantaneously but moves from WeightCurrent to AnimationTrack.WeightTarget. The time it takes to do this is determined by the fadeTime parameter given when the animation is played, or the weight is adjusted.

WeightCurrent can be checked against AnimationTrack.WeightTarget to see if the desired weight has been reached. Note that these values should not be checked for equality with the == operator, as both of these values are floats. To see if WeightCurrent has reached the target weight, it is recommended to see if the distance between those values is sufficiently small (see code sample below).

The animation weighting system is used to determine how AnimationTracks playing at the same priority are blended together. The default weight is one, and no movement will be visible on an AnimationTrack with a weight of zero. The pose that is shown at any point in time is determined by the weighted average of all the Poses and the WeightCurrent of each AnimationTrack. In most cases blending animations is not required and using AnimationTrack.Priority is more suitable.

Code Samples

WeightCurrent and WeightTarget

local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
while not localPlayer.Character do
task.wait()
end
local character = localPlayer.Character
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animation1 = Instance.new("Animation")
animation1.AnimationId = "rbxassetid://507770453"
local animation2 = Instance.new("Animation")
animation2.AnimationId = "rbxassetid://507771019"
task.wait(3) -- arbitrary wait time to allow the character to fall into place
local animationTrack1 = animator:LoadAnimation(animation1)
local animationTrack2 = animator:LoadAnimation(animation2)
animationTrack1.Priority = Enum.AnimationPriority.Movement
animationTrack2.Priority = Enum.AnimationPriority.Action
animationTrack1:Play(0.1, 5, 1)
animationTrack2:Play(10, 3, 1)
local done = false
while not done and task.wait(0.1) do
if math.abs(animationTrack2.WeightCurrent - animationTrack2.WeightTarget) < 0.001 then
print("got there")
done = true
end
end

Methods

AdjustSpeed

void

This function changes the AnimationTrack.Speed of an animation. A positive value for speed plays the animation forward, a negative one plays it backwards, and 0 pauses it.

An AnimationTrack's initial speed is set as a parameter in AnimationTrack:Play(). However a track's Speed can be changed during playback, using AdjustSpeed. When speed is equal to 1, the amount of time an animation takes to complete is equal to AnimationTrack.Length (in seconds).

When is adjusted, then the actual time it will take a track to play can be computed by dividing the length by the speed. Speed is a unitless quantity.

Speed can be used to link the length of an animation to different gameplay events (for example recharging an ability) without having to upload different variants of the same animation.

Parameters

speed: number

The playback speed the animation is to be changed to.

Default Value: 1

Returns

void

Code Samples

Playing Animation for a Specific Duration

local function playAnimationForDuration(animationTrack, duration)
local speed = animationTrack.Length / duration
animationTrack:Play()
animationTrack:AdjustSpeed(speed)
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765000"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
playAnimationForDuration(animationTrack, 3)
Animation Speed

local ContentProvider = game:GetService("ContentProvider")
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
while not localPlayer.Character do
task.wait()
end
local character = localPlayer.Character
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507770453"
ContentProvider:PreloadAsync({ animation })
local animationTrack = animator:LoadAnimation(animation)
local normalSpeedTime = animationTrack.Length / animationTrack.Speed
animationTrack:AdjustSpeed(3)
local fastSpeedTime = animationTrack.Length / animationTrack.Speed
print("At normal speed the animation will play for", normalSpeedTime, "seconds")
print("At 3x speed the animation will play for", fastSpeedTime, "seconds")

AdjustWeight

void

Changes the weight of an animation, with the optional fadeTime parameter determining how long it takes for AnimationTrack.WeightCurrent to reach AnimationTrack.WeightTarget.

When weight is set in an AnimationTrack it does not change instantaneously but moves from WeightCurrent to AnimationTrack.WeightTarget. The time it takes to do this is determined by the fadeTime parameter given when the animation is played, or the weight is adjusted.

WeightCurrent can be checked against AnimationTrack.WeightTarget to see if the desired weight has been reached. Note that these values should not be checked for equality with the == operator, as both of these values are floats. To see if WeightCurrent has reached the target weight, it is recommended to see if the distance between those values is sufficiently small (see code sample below).

The animation weighting system is used to determine how AnimationTracks playing at the same priority are blended together. The default weight is one, and no movement will be visible on an AnimationTrack with a weight of zero. The pose that is shown at any point in time is determined by the weighted average of all the Poses and the WeightCurrent of each AnimationTrack. See below for an example of animation blending in practice. In most cases blending animations is not required and using AnimationTrack.Priority is more suitable.

Parameters

weight: number

The weight the animation is to be changed to.

Default Value: 1
fadeTime: number

The duration of time that the animation will fade between the old weight and the new weight for.

Default Value: 0.100000001

Returns

void

Code Samples

AnimationTrack Change Weight

local function changeWeight(animationTrack, weight, fadeTime)
animationTrack:AdjustWeight(weight, fadeTime)
local startTime = tick()
while math.abs(animationTrack.WeightCurrent - weight) > 0.001 do
task.wait()
end
print("Time taken to change weight " .. tostring(tick() - startTime))
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
changeWeight(animationTrack, 0.6, 1)

GetMarkerReachedSignal

This function returns an event similar to the AnimationTrack.KeyframeReached event, except it only fires when a specified KeyframeMarker has been hit in an animation. The difference allows for greater control of when the event will fire.

To learn more about using this function, see Animation Events in the Animation Editor article.

More About Keyframes

Keyframe names can be set in the Roblox Animation Editor when creating or editing an animation. They cannot, however, be set by a Script on an existing animation prior to playing it.

Keyframe names do not need to be unique. For example, if an Animation has three keyframes named "EmitParticles," the connected event returned by this function will fire each time one of these keyframes is reached.

See also:

Parameters

name: string

The name of the KeyFrameMarker the signal is being created for.


Returns

The signal created and fired when the animation reaches the created KeyFrameMarker.

Code Samples

Listening to Keyframe Markers

local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character or player.Character:Wait()
local humanoid = character:WaitForChild("Humanoid")
-- Create new "Animation" instance
local kickAnimation = Instance.new("Animation")
-- Set its "AnimationId" to the corresponding animation asset ID
kickAnimation.AnimationId = "rbxassetid://2515090838"
-- Load animation onto the humanoid
local kickAnimationTrack = humanoid:LoadAnimation(kickAnimation)
-- Play animation track
kickAnimationTrack:Play()
-- If a named event was defined for the animation, connect it to "GetMarkerReachedSignal()"
kickAnimationTrack:GetMarkerReachedSignal("KickEnd"):Connect(function(paramString)
print(paramString)
end)

GetTimeOfKeyframe

Returns the time position of the first Keyframe of the given name in an AnimationTrack. If multiple Keyframes share the same name, it will return the earliest one in the animation.

This function will return an error if it is uses with an invalid keyframe name (one that does not exist for example) or if the underlying Animation has not yet loaded. To address this make sure only correct keyframe names are used and the animation has loaded before calling this function.

To check if the animation has loaded, verify that the AnimationTrack.Length is greater than zero.

Parameters

keyframeName: string

The name associated with the Keyframe to be found.


Returns

The time, in seconds, the Keyframe occurs at normal playback speed.

Code Samples

Jump To Keyframe

local function jumpToKeyframe(animationTrack, keyframeName)
local timePosition = animationTrack:GetTimeOfKeyframe(keyframeName)
if not animationTrack.IsPlaying then
animationTrack:Play()
end
animationTrack.TimePosition = timePosition
end
local ANIMATION_ID = 0
local KEYFRAME_NAME = "Test"
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://" .. ANIMATION_ID
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
jumpToKeyframe(animationTrack, KEYFRAME_NAME)

Play

void

When AnimationTrack:Play() is called the track's animation will begin playing and the weight of the animation will increase from 0 to the specified weight (defaults to 1) over the specified fadeTime (defaults to 0.1).

The speed the AnimationTrack will play at is determined by the speed parameter (defaults to 1). When the speed is equal to 1 the number of seconds the track will take to complete is equal to the track's AnimationTrack.Length property. For example, a speed of 2 will cause the track to play twice as fast.

The weight and speed of the animation can also be changed after the animation has begun playing by using the AnimationTrack:AdjustWeight() and AnimationTrack:AdjustSpeed() methods.

If the developer wants to start the animation at a specific point using AnimationTrack.TimePosition, it is important the animation is played before this is done.

Parameters

fadeTime: number

The duration of time that the animation's weight should be faded in for.

Default Value: 0.100000001
weight: number

The weight the animation is to be played at.

Default Value: 1
speed: number

The playback speed of the animation.

Default Value: 1

Returns

void

Code Samples

Playing Animation for a Specific Duration

local function playAnimationForDuration(animationTrack, duration)
local speed = animationTrack.Length / duration
animationTrack:Play()
animationTrack:AdjustSpeed(speed)
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765000"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
playAnimationForDuration(animationTrack, 3)
Freeze Animation at Position

function freezeAnimationAtTime(animationTrack, timePosition)
if not animationTrack.IsPlaying then
-- Play the animation if it is not playing
animationTrack:Play()
end
-- Set the speed to 0 to freeze the animation
animationTrack:AdjustSpeed(0)
-- Jump to the desired TimePosition
animationTrack.TimePosition = timePosition
end
function freezeAnimationAtPercent(animationTrack, percentagePosition)
if not animationTrack.IsPlaying then
-- Play the animation if it is not playing
animationTrack:Play()
end
-- Set the speed to 0 to freeze the animation
animationTrack:AdjustSpeed(0)
-- Jump to the desired TimePosition
animationTrack.TimePosition = (percentagePosition / 100) * animationTrack.Length
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
freezeAnimationAtTime(animationTrack, 0.5)
freezeAnimationAtPercent(animationTrack, 50)

Stop

void

Stops the AnimationTrack. Once called playback of the AnimationTrack will stop and the weight of the animation will move towards zero over a length of time specified by the optional fadeTime parameter.

For example, if Stop is called with a fadeTime of 2 seconds it will take two seconds for the weight of the AnimationTrack to reach zero and its effects completely end. Please note this will be the case regardless of the initial weight of the animation.

It is not recommended to use a fadeTime of 0 seconds to try to override this effect and end the animation immediately as presently, this causes the AnimationTrack poses to freeze.

Parameters

fadeTime: number

The time, in seconds, for which animation weight is to be faded out over.

Default Value: 0.100000001

Returns

void

Code Samples

AnimationTrack Stop

local function fadeOut(animationTrack, fadeTime)
animationTrack:Stop(fadeTime)
local startTime = tick()
while animationTrack.WeightCurrent > 0 do
task.wait()
end
local timeTaken = tick() - startTime
print("Time taken for weight to reset: " .. tostring(timeTaken))
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
animationTrack:Play()
fadeOut(animationTrack, 1)

Events

DidLoop

This event fires whenever a looped AnimationTrack completes a loop, on the next update.

Currently it may also fire at the exact end of a non looped animation track but this behavior should not be relied upon.


Code Samples

Play AnimationTrack for a Number of Loops

local function playForNumberLoops(animationTrack, number)
animationTrack.Looped = true
animationTrack:Play()
local numberOfLoops = 0
local connection = nil
connection = animationTrack.DidLoop:Connect(function()
numberOfLoops = numberOfLoops + 1
print("loop: ", numberOfLoops)
if numberOfLoops >= number then
animationTrack:Stop()
connection:Disconnect() -- it's important to disconnect connections when they are no longer needed
end
end)
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
playForNumberLoops(animationTrack, 5)

Ended

Fires when the AnimationTrack is completely done moving anything in the world. The animation has finished playing, the "fade out" is finished, and the subject is in a neutral pose.

You can use this to take action when the animation track's subject is back in a neutral pose that's unaffected by the AnimationTrack or to clean up the AnimationTrack. or any associated Connections.


Code Samples

AnimationTrack Ended

local InsertService = game:GetService("InsertService")
local Players = game:GetService("Players")
-- Create an NPC model to animate.
local npcModel = Players:CreateHumanoidModelFromUserId(129687796)
npcModel.Name = "JoeNPC"
npcModel.Parent = workspace
npcModel:MoveTo(Vector3.new(0, 15, 4))
local humanoid = npcModel:WaitForChild("Humanoid")
-- Load an animation.
local animationModel = InsertService:LoadAsset(2510238627)
local animation = animationModel:FindFirstChildWhichIsA("Animation", true)
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
-- Connect to Stopped event. This fires when animation stops of
-- it's own accord, or we explicitly call Stop.
animationTrack.Stopped:Connect(function()
print("Animation stopped")
end)
-- Connect to Ended event. This fires when when animation is completely
-- finished affecting the world. In this case it will fire 3 seconds
-- after we call animationTrack:Stop because we pass in a 3
-- second fadeOut.
animationTrack.Ended:Connect(function()
print("Animation ended")
animationTrack:Destroy()
end)
-- Run, give it a bit to play, then stop.
print("Calling Play")
animationTrack:Play()
task.wait(10)
print("Calling Stop")
animationTrack:Stop(3)

KeyframeReached

Fires every time playback of an AnimationTrack reaches a Keyframe that does not have the default name - "Keyframe."

This event allows a developer to run code at predefined points in an animation (set by Keyframe names). This allows the default functionality of Roblox animations to be expanded upon by adding Sounds or ParticleEffects at different points in an animation.

Keyframe names do not need to be unique. For example, if an Animation has three keyframes named "Particles" the KeyframeReached event will fire each time one of these keyframes is reached.

Keyframe names can be set in the Roblox Animation Editor when creating or editing an animation. They cannot however be set by a Script on an existing animation prior to playing it.

Parameters

keyframeName: string

The name of the Keyframe reached.


Code Samples

AnimationTrack KeyframeReached

local Players = game:GetService("Players")
local player = Players:GetChildren()[1]
local character = workspace:WaitForChild(player.Name)
local humanoid = character:WaitForChild("Humanoid")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://437855404"
local animTrack = humanoid:LoadAnimation(animation)
animTrack.KeyframeReached:Connect(function(keyframeName)
print("Keyframe reached:" .. keyframeName)
end)
animTrack:Play()
Listen For Animation Effects

local function listenForAnimationEffects(humanoid) -- would also work for an AnimationController
-- listen for new animations being played on the Humanoid
humanoid.AnimationPlayed:Connect(function(animationTrack)
local keyframeConnection = nil
-- listen for the 'Effect' keyframe being reached
keyframeConnection = animationTrack.KeyframeReached:Connect(function(keyframeName)
if keyframeName == "Effect" then
-- make sure the Humanoid RootPart exists
if humanoid.RootPart then
-- create a basic particle effect
local particles = Instance.new("ParticleEmitter")
particles.Parent = humanoid.RootPart
particles.Rate = 0
particles:Emit(10)
task.delay(2, function()
if particles then
particles:Destroy()
end
end)
end
end
end)
local stoppedConnection = nil
stoppedConnection = animationTrack.Stopped:Connect(function()
-- clean up old connections to stop memory leaks
keyframeConnection:Disconnect()
stoppedConnection:Disconnect()
end)
end)
end
local humanoid = script.Parent:WaitForChild("Humanoid")
listenForAnimationEffects(humanoid)

Stopped

Fires whenever the AnimationTrack finishes playing.

This event has a number of uses. It can be used to wait until an AnimationTrack has stopped before continuing (for example, if chaining a series of animations to play after each other). It can also be used to clean up any Instances created during the animation playback.


Code Samples

AnimationTrack Stopped

local function yieldPlayAnimation(animationTrack, fadeTime, weight, speed)
animationTrack:Play(fadeTime, weight, speed)
animationTrack.Stopped:Wait()
print("Animation has stopped")
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://507765644"
local humanoid = script.Parent:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local animationTrack = animator:LoadAnimation(animation)
yieldPlayAnimation(animationTrack, 1, 0.6, 1)