Technology Article

Skeletal Animation

Accessing animations

Animations can be accessed from a number of different sources. The most common source is from animated entities. When you have a mesh that is skeletally animated, and then create a luster.display.Entity from that mesh, you have access to AnimationState objects. Named animations are controlled through the AnimationState class.

Getting available animations

You can access an entity's available animations through the animationNames property. This returns a lua table that is an array of animation names. You can trace the available animations like this:

local anims = entity.animationNames
for i,v in ipairs(anims) do
	trace(v)
end

Updating available animations

Sometimes the animations available through an entity will change. This can happen if you have programmatically created new animations. To ensure that this animation appears in the list of available animations you should call refreshAnimations.

entity:refreshAnimations()

Getting the AnimationState

You need to retrieve the AnimationState object for the given animation from the entity in order to control it.

local anim = entity:getAnimationState(animName)

Once you have this animation (getAnimationState returns nil if the animation is not found) then you can use the methods on the AnimationState object to control it.

Playing and stopping animations

In order to play the animation you can use the play method. It's important to note that animations have an enabled flag, and to ensure that an animation plays when you want it to you should set this flag to true.

anim.enabled = true
anim:play()

At any time you can either disable the animation by setting enabled=false or you may called the pause method.

anim:pause()

Advanced playback

Weights

There are a number of properties and methods in the AnimationState class which let you customize how the animation affects the entity. The weight property specifies how much the animation actually changes the entity. A weight of 0 makes it so the animation is essentially disabled, while a weight of 1 means the animation has the full affect.

Looping

You can specify that an animation loops using the loop property. Set it to true to cause the animation to automatically loop.

Custom playback

You can gain more control over playback by not using the play/pause methods. Instead, enable the animation as normal and then use either the time property or the addTime method to cause the animation to move forward. Set the time property or pass in the time parameter to addTime as seconds. In this way you can simulate slower or faster playback of the animation, or even runt he animation in reverse.

Listeners

AnimationState derives from luster.EventDispatcher and it throws a single event. This is AnimationState.ENDED, and it is thrown when the animation state has finished playing. Note that this event will not be thrown if looping is turn on, as the animation will automatically start over.

anim:addEventListener(luster.animation.AnimationState.ENDED, function() end)

Note that their is also a property on the object called ended, which is set to true when the animation is finished playing. You can use this property to poll for when the animation has finished.

if anim.ended then
	-- Custom processing after animation is done
end