XNA Game Studio 4.0 provides easy-to-use APIs that
enable you to animate and render the avatar for the players in your game
or to generate random avatars for users within your game. Avatars
provide an easy way to add characters to your game without requiring an
artist to create numerous character models. They also provide a level of
user customization to your game that users find enjoyable.
Avatars are a popular feature used in many of the top Xbox Live Indie games.
Introduction to Avatars
The avatar APIs in XNA Game
Studio 4.0 provide a high-level abstraction that provides the capability
to animate and render avatars with a simple API. The process of loading
and managing the models and textures used to draw the avatars is hidden
from the developer. Figure 1 shows what a avatar looks like.
The
avatar functionality is included in the Microsoft.Xna.Framework.Avatars
assembly, which is available to the Xbox 360 and Windows platforms.
Although the assembly is available on Windows, it is not possible to
draw avatars on Windows. The Windows APIs are provided to minimize the
amount of platform-specific defines needed in your code.
Accessing Avatar Information Using AvatarDescription
An avatar has many customizable components from gender, height, size, clothing, and accessories. Each user has his or her own AvatarDescription that stores all of the customizable choices the user has made when building the avatar. The AvatarDescription contains an internal opaque data buffer that stores all of these choices. The AvatarDescription is used to tell the AvatarRender which model assets and textures should be used for a specific avatar.
Accessing a Gamer’s AvatarDescription
The AvatarDescription class provides an asynchronous method BeginGetFromGamer to access the AvatarDescription for any type that inherits from the Gamer base type. The most common scenario in your game is to load the AvatarDescription for one of the SignedInGamer players in your game.
Let’s see how to access an AvatarDescription from a SignedInGamer. First, add a member variable to your games class to store the AvatarDescription.
AvatarDescription avatarDescription;
Next, in the games constructor, add the following two lines of code.
Components.Add(new GamerServicesComponent(this));
SignedInGamer.SignedIn += new EventHandler<SignedInEventArgs>(SignedInGamer_SignedIn);
The first line adds the GamerServiceComponent to the game’s Components list. This ensures that the GamerServicesDispatcher is regularly updated as the game runs.
The second line creates a
new event handler that is fired anytime a player signs into the game.
Even if a player is signed into Xbox when your game launches, the SignedInGamers
collection will not populate for a number of frames. You can poll the
collection yourself, but signing up for this event ensures you are
notified anytime a player signs into the console.
The next bit of code to add is the new SignedInGamer_SignedIn method that is called when the SignedIn event fires. Add the following method to your game class:
void SignedInGamer_SignedIn(object sender, SignedInEventArgs e)
{
// Only handle player one sign in
if (e.Gamer.PlayerIndex == PlayerIndex.One)
{
AvatarDescription.BeginGetFromGamer(e.Gamer, LoadGamerAvatar, null);
}
}
For this example, you want to request only the first player’s AvatarDescription, so check the SignedInEventArgs PlayerIndex property to see whether this event was fired for the first player. If you have the correct player, you then kick off the BeginGetFromGamer asynchronous method. BeginGetFromGamer is passed the instance of the Gamer object and a AsyncCallback method that you will implement.
To implement the LoadGamerAvatar AsyncCallback method, add the following method to your game’s class.
void LoadGamerAvatar(IAsyncResult result)
{
// Get the AvatarDescription for the gamer
avatarDescription = AvatarDescription.EndGetFromGamer(result);
// Is the AvatarDescription valid
if (avatarDescription.IsValid)
// Use the AvatarDescription and load AvatarRenderer
}
In the callback method, first call EndGetFromGamer method, which returns AvatarDescription. After the AvatarDescription has been returned, it is possible that the user did not have a valid avatar set for his or her profile. In that case, the IsValid property returns false. On Windows the returned AvatarDescription always returns false for IsValid.
Creating a Random AvatarDescription
Along
with the players’ avatars, you might also want to display more avatars
to represent other nonpayer characters in your game. In that case, you
can create random avatars.
To create a random AvatarDescription, the static CreateRandom method is provided.
AvatarDescription description = AvatarDescription.CreateRandom();
This creates either a
random female or male avatar that your game can then use. If you want to
specify a gender for the avatar, you can use the CreateRandomAvatarBodyType enumeration argument. The AvatarBodyType enumeration has two values of Female and Male. overload, which takes an
AvatarDescription description = AvatarDescription.CreateRandom(AvatarBodyType.Female);
The AvatarDescription.BodyType property can be used to determine the gender of an existing AvatarDescription. It returns the AvatarBodyType for the already created AvatarDescription.
The AvatarDescription.Height property returns a float
value representing the avatar’s height in meters. This is the size of
the avatar skeleton from the bottom of the feet to the top of the head.
This does not take into account any type of hat or other clothing item
that might be on the head.
Constructing an AvatarDescription from a Byte Array
The AvatarDescription
class provides a third way to create a new instance of the type. It
provides a constructor that takes the opaque description as a byte
array. This constructor can be useful in a couple of scenarios. The
first is to enable the player to select random characters in your game
and then save his or her selection so the same avatar can be used across
play sessions.
To obtain the byte array from the existing AvatarDescription, use the following Description property:
byte[] opaqueBlob = avatarDescription.Description;
AvatarDescription copyAvatarDescription = new AvatarDescription(opaqueBlob);
The second scenario where the byte
array constructor is useful is for customizing the nonplayer character
avatars in your game. For example, you have a shopkeeper in your game
that you want to customize to have a beard and top hat. This can be
accomplished by first customizing the avatar in the dashboard avatar
editor. Then, load the AvatarDescription for that player. Next, use the debugger to print out the Description property to the debugger. Figure 2 shows the AvatarDescription in the debug window.
You can then copy, paste, and format the values into a byte array in your source code. This hard-coded array can then be used to create a new instance of the AvatarDescription.
Note
Xbox
Live Indie Games prohibits utilizing avatar clothing and other assets
that have been unlocked or purchased through the avatar marketplace
unless they are outfitted on the player’s avatar. So if you are creating
a custom avatar for a nonplayer character, you are restricted in using
only the built-in avatar assets and can’t use items you purchased from
the avatar marketplace.
The Changed Event
AvatarDescription provides an event called Changed. This event can fire while your game is running in the event that the user has updated his or her avatar.