Loading Avatar Animations with AvatarAnimation
There are a number of
built-in animations that enable you to quickly animate an avatar in your
game. The animations that are provided were created for use in the Xbox
dashboard and consist of idle animations along with some expressive
animations like celebrate and clap.
To add an animation to
your game, the first thing you need is a new member variable in your
game to hold the animation. Add the following member variable to your
game:
AvatarAnimation avatarAnimation;
Next, in the game’s LoadContent method, you can load the following celebrate animation:
// Load celebrate animation
avatarAnimation = new AvatarAnimation(AvatarAnimationPreset.Celebrate);
The AvatarAnimation constructor takes an AvatarAnimationPreset enumeration to specify which animation to load. Table 1 shows all of the built-in animation types that are defined by the AvatarAnimationPreset enumeration.
Table 1. AvatarAnimationPreset Enumerations
Celebrate | MaleIdleCheckHand |
Clap | MaleIdleLookAround |
FemaleAngry | MaleIdleShiftWeight |
FemaleConfused | MaleIdleStretch |
FemaleCry | MaleLaugh |
FemaleIdleCheckNails | MaleSurprised |
FemaleIdleFixShoe | MaleYawn |
FemaleIdleLookAround | Stand0 |
FemaleIdleShiftWeight | Stand1 |
FemaleLaugh | Stand2 |
FemaleShocked | Stand3 |
FemaleShocked | Stand4 |
FemaleYawn | Stand5 |
MaleAngry | Stand6 |
MaleConfused | Stand7 |
MaleCry | Wave |
Updating the Animation
There are two methods that you can use to update the current playback
position of the animation. The first and easiest way is to use the Update method. The Update method takes a TimeSpan
for the current frame’s elapsed time and a boolean value that indicates
whether the animation should be looped when it reaches the end of the
animation.
To update the animation, add the following to your game’s Update method:
// Update the animation with the elapsed frame time
// Set the looping parameter to true
avatarAnimation.Update(gameTime.ElapsedGameTime, true);
The gameTime.ElapsedGameTime TimeSpan is used for the current frame’s length. This updates the animation in sync with how fast your game is updating. The value of true is passed for the loop argument so that the animation loops when it reaches the end of the animation.
The second method for updating the avatar’s playback location is to set the value explicitly. The AvatarAnimation CurrentPosition property is a TimeSpan
value that represents the amount of time from the start of the
animation. This value can be set to any valid range from 0 to the end
length of the animation. The length of the animation can be retrieved by
using the Length property of the animation.
Transforms and Expression of the Animation
The animation returns two sets of values for the current playback
position. The first is the location for each of the bones in the avatar
skeleton. The BoneTransforms property returns a ReadOnlyCollection of Matrix values for each of the bone positions and orientations.
The second set of animation
values are for the textures to use for the avatar’s face. Although the
body uses skeletal animation to transform the vertices of the avatar,
the face is made up of textures for the eyes, eyebrows, and mouth. The AvatarAnimation provides the Expression property to return an AvatarAnimation structure.
The AvatarAnimation structure provides properties for the LeftEye, RightEye, LeftEyebrow, RightEyebrow, and Mouth. Each of these represents the texture to use for the corresponding facial feature.
Table 2 shows the AvatarEye enumeration values.
Table 2. AvatarEye Enumerations
Angry | LookRight |
Blink | LookUp |
Confused | Neutral |
Happy | Sad |
Laughing | Shocked |
LookDown | Sleeping |
LookLeft | Yawning |
Table 3 shows the AvatarEyebrow enumeration values.
Table 3. AvatarEyebrow Enumerations
Angry | Raised |
Confused | Sad |
Neutral | |
Table 4 shows the AvatarMouth enumeration values.
Table 4. AvatarMouth Enumerations
Angry | PhoneticEe |
Confused | PhoneticFv |
Happy | PhoneticL |
Laughing | PhoneticO |
Neutral | PhoneticW |
PhoneticAi | Sad |
PhoneticDth | Shocked |
Avatar Animation Functionality Though an Interface
Although
the built-in avatar animations are convenient, you might want to
provide your own custom animations or to programmatically generate
animations using IK. The IAvatarAnimation interface is provided to enable you to create your own custom avatar playback systems that work with the avatar system.
The IAvatarAnimation interface exposes four properties: BoneTransforms, CurrentPosition, Expression, and Length. It also exposes one method: Update. The built-in AvatarAnimation type implements the IAvatarAnimation interface so you can combine your animation playback system with the built-in animations.
Drawing the Avatar Using AvatarRenderer
Now that you have loaded the AvatarDescription and have an AvatarAnimation to play, you just need models and textures for the avatar and draw them to the screen. This is precisely what the AvatarRenderer type does.
To draw the avatar in the game, you need to add a member variable to store the AvatarRenderer. Add the following member variables to your game class:
AvatarRenderer avatarRenderer;
Matrix world;
Matrix view;
Matrix projection;
In the game’s LoadContent method, create an instance of the AvatarRenderer from one of the previous AvatarDescription instances you created previously.
// Load avatar renderer for random description
avatarRenderer = new AvatarRenderer(avatarDescription);
// Rotate avatar to face the screen
world = Matrix.CreateRotationY(MathHelper.Pi);
// Set view and projection matrices to something sensible
view = Matrix.CreateLookAt(new Vector3(0, 1, 3), new Vector3(0, 1, 0), Vector3.Up);
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
GraphicsDevice.Viewport.AspectRatio,
0.01f, 200.0f);
After creating a new instance of the AvatarRenderer, set default values for the world, view, and projection matrices. By default, the avatar faces in the negative Z direction, so set the world matrix to rotate around the Y axis.
If you are using the asynchronous AvatarDescription.BeginGetFromGamer method, then you can load the AvatarRenderer in the AsyncCallback method that you pass to BeginGetFromGamer.
The last bit of code is to draw the avatar. In your game’s Draw method add the following lines of code:
// Set the world, view, and projection matrices
avatarRenderer.World = world;
avatarRenderer.View = view;
avatarRenderer.Projection = projection;
// Draw the avatar to the current render target
avatarRenderer.Draw(avatarAnimation);
Before you draw, first set the World, View, and Projection matrices on the AvatarRenderer instance. You can simply call the Draw method passing in any AvatarAnimation or other type that implements the IAvatarAnimation interface.
Running the sample should look like Figure 3.
Drawing While Loading an Avatar
Although the AvatarRenderer
constructor is not asynchronous and it returns immediately the loading,
the geometry and textures that make up the avatar can take a few
frames. During that time, if you call the Draw method, notice an animated swirling pattern like that shown in Figure 4.
If you don’t want to display the loading effect, you can use the overload of the AvatarRenderer constructor that takes a boolean value for the useLoadingEffect parameter. Passing in false causes the loading effect to not display while the avatar is loading.
Deterring the Current State of the AvatarRenderer
At times, you might want to query the state of the AvatarRenderer to see whether it has completed loading. The State property can be used to determine the current state of an AvatarRenderer instance. The return value is an AvatarRendererState enumeration that can have three values of Loading, Ready, and Unavailable. The Loading and Ready states are self-explanatory. The Unavailable state is a special case that occurs in a couple of situations. The first is on Windows when any AvatarRenderer instance returns Unavailable because avatars can’t be rendered on Windows.
The second situation is when the models and textures that make up the
avatar are corrupted on the Xbox and can’t be downloaded.
Note
When avatars were first
introduced, their proportions were not close to those of a real person.
For example, their arms were too short. To help support player mapping
between their avatar and their body using Kinect, the proportions of the
avatars were updated to better match those of a human. The new avatars
are referred to as V2 avatars. XNA Game Studio 4.0 utilizes V2 avatars.