Nerd Herder

Dean Johnson blogs about life on the XNA platform and tools team

Simple example on how to load a signed in gamers avatar

Simple example on how to load a signed in gamers avatar

Rate This
  • Comments 1

Now that XNA Game Studio 3.1 has been released I have had time to notice the types of questions people are asking on the forums about avatars. One question that has come up a few times is how to load a signed in gamers avatar. There are a couple of pitfalls. One thing that can be confusing to developers is that a SignedInGamer from the Gamer.SignedInGamers collection may be null for the first few frames when the game loads. So when a developer tries to read the Avatar property of a signed in gamer they will receive a null reference exception. The developer needs to wait until the gamer is recognized as being signed in and then attempt to load the players avatar. You game should not just check for the signed in gamer in a tight loop. Your game should go about doing other things like updating input and rendering. Games also need to handle the case where the signed in gamer doesn't have an avatar.

There are a few ways to wait for the SignedInGamer to not be null and load the appropriate avatar. I will show a couple of methods. The first just polls and checks to see if the signed in gamer is not null and when it is not it loads the players avatar. If the player doesn't have an avatar a random one is created. Also if the system takes longer than 3 seconds for the gamer to sign then the code will load a random one instead. Below is an example of the first method.

public class SimpleAvatarGame : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;

    AvatarDescription avatarDescription;
    AvatarRenderer avatarRenderer;
    AvatarAnimation avatarAnimation;

    public SimpleAvatarGame()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        graphics.PreferMultiSampling = true;
        graphics.PreferredBackBufferWidth = 1280;
        graphics.PreferredBackBufferHeight = 720;

        Components.Add(new GamerServicesComponent(this)); 
    }

    protected override void LoadContent()
    {
        avatarAnimation = new AvatarAnimation(AvatarAnimationPreset.Celebrate);
    }

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        LoadUserAvatar(gameTime);

        // You may want to check that the avatar renderer has loaded
        // so that the animation does not start playing until it has loaded
        avatarAnimation.Update(gameTime.ElapsedGameTime, true);

        base.Update(gameTime);
    }

    /// <summary>
    /// Load player one's avatar
    /// </summary>
    private void LoadUserAvatar(GameTime gameTime)
    {
        // Avatar may already be loaded
        if (avatarRenderer != null)
            return;

        // Check to see if the user is signed in
        if (Gamer.SignedInGamers[PlayerIndex.One] != null)
        {
            // Get the users avatar description
            avatarDescription = Gamer.SignedInGamers[PlayerIndex.One].Avatar;

            // If this is not valid the user doen't have an avatar
            if (!avatarDescription.IsValid)
            {
                avatarDescription = AvatarDescription.CreateRandom();
            }

            avatarRenderer = new AvatarRenderer(avatarDescription);
        }
        // Check to see if it has been longer than 3 seconds
        else if (gameTime.TotalGameTime.TotalSeconds > 3)
        {
            avatarDescription = AvatarDescription.CreateRandom();
            avatarRenderer = new AvatarRenderer(avatarDescription);
        }
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        if (avatarRenderer != null)
        {
            avatarRenderer.World = Matrix.CreateRotationY(MathHelper.ToRadians(180.0f));
            avatarRenderer.View = Matrix.CreateLookAt(new Vector3(0, 1, 3), new Vector3(0, 1, 0), Vector3.Up);
avatarRenderer.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
GraphicsDevice.Viewport.AspectRatio, .01f, 200.0f); avatarRenderer.Draw(avatarAnimation.BoneTransforms, avatarAnimation.Expression); } base.Draw(gameTime); } }

Another technique for determining when the gamer has signed in and to read their Avatar property is to subscribe to the SignedInGamer.SignedIn event handler. Below is an example how to do this.

public class SimpleAvatarGame : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;

    AvatarDescription avatarDescription;
    AvatarRenderer avatarRenderer;
    AvatarAnimation avatarAnimation;

    public SimpleAvatarGame()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        graphics.PreferMultiSampling = true;
        graphics.PreferredBackBufferWidth = 1280;
        graphics.PreferredBackBufferHeight = 720;

        Components.Add(new GamerServicesComponent(this));

        SignedInGamer.SignedIn += new EventHandler<SignedInEventArgs>(LoadGamerAvatar); 
    }

    void LoadGamerAvatar(object sender, SignedInEventArgs e)
    {
        avatarDescription = e.Gamer.Avatar;

        // Check to see if the player has an avatar
        if (!avatarDescription.IsValid)
        {
            avatarDescription = AvatarDescription.CreateRandom();
        }

        avatarRenderer = new AvatarRenderer(avatarDescription);
    } 

    protected override void LoadContent()
    {
        avatarAnimation = new AvatarAnimation(AvatarAnimationPreset.Celebrate);
    }

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        // You may want to check that the avatar renderer has loaded
        // so that the animation does not start playing until it has loaded
        avatarAnimation.Update(gameTime.ElapsedGameTime, true);

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        if (avatarRenderer != null)
        {
            avatarRenderer.World = Matrix.CreateRotationY(MathHelper.ToRadians(180.0f));
avatarRenderer.View = Matrix.CreateLookAt(new Vector3(0, 1, 3), new Vector3(0, 1, 0), Vector3.Up); avatarRenderer.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
GraphicsDevice.Viewport.AspectRatio, .01f, 200.0f); avatarRenderer.Draw(avatarAnimation.BoneTransforms, avatarAnimation.Expression); } base.Draw(gameTime); } }

If you have any questions please ask on the forums here http://forums.xna.com

  • The second one is the option I prefer. Nice post.

Page 1 of 1 (1 items)
Leave a Comment
  • Please add 8 and 6 and type the answer here:
  • Post
Translate This Page
Search
Archive