CrossFade

May 20, 2010 at 4:42 PM

I've been using this code to switch smoothly between animations.

protected void UpdateInput(GameTime gameTime)
        {
            KeyboardState keyboardState = Keyboard.GetState();
            KeyboardState lastKeyboardState = Keyboard.GetState();

            if (keyboardState.IsKeyDown(Keys.A))
            {
                move -= 0.5f;
                Component.AnimationController.PlayClip(Component.SkinnedModel.AnimationClips["Walk"]);
            }

            else if (keyboardState.IsKeyDown(Keys.D))
            {
                move += 0.5f;

                Component.AnimationController.PlayClip(Component.SkinnedModel.AnimationClips["Walk"]);
            }
            
            else
            {
                Component.AnimationController.CrossFade(Component.SkinnedModel.AnimationClips["Stance"], TimeSpan.FromMilliseconds(300));
            }

            lastKeyboardState = keyboardState;
            lookAtMe.myPosition = new Vector3(lookAtMe.myPosition.X, move, lookAtMe.myPosition.Z);
        }

The idea here is that when the model starts/stops walking they move smoothly to/from  the stance animation. If I use the PlayClip on all three the transition is a bit too sharp. However, the solution above seems to be only playing the Walk animation. The Stance animation seems to be frozen, or perhaps only playing the first keyframe.  Have I made a mistake?

Editor
May 20, 2010 at 9:50 PM

ive not actually used animated models at all, but the animated model framework belongs to the XNAnimation library, you hay well find better help on their site.

http://xnanimation.codeplex.com/

give it a go, of course if someone here knows the answer they will post it too :)

bubzy.

May 24, 2010 at 1:45 PM

XNAnimation discussions seem a bit quiet, tumbleweed town :) I'll mess around with it myself, if i solve the problem, I'll post it here. Otherwise I'll just use the standard jump between the animations, it's not too bad.

May 24, 2010 at 8:57 PM

This code solves the crossfade problem, but at the moment, it doesn't allow the character to move.

 protected void UpdateInput(GameTime gameTime)
        {
            KeyboardState keyboardState = Keyboard.GetState();
            
            if (keyboardState.IsKeyDown(Keys.Left) && lastKeyboardState.IsKeyUp(Keys.Left))
            {
                move -= 0.5f;
                activeAnimationClipIndex = ((activeAnimationClipIndex - 1) < 0) ?
                    Component.SkinnedModel.AnimationClips.Count - 1 : activeAnimationClipIndex - 1;
                Component.AnimationController.CrossFade(Component.SkinnedModel.AnimationClips.Values[activeAnimationClipIndex],
                    TimeSpan.FromMilliseconds(300));
            }

            if (keyboardState.IsKeyDown(Keys.Right) && lastKeyboardState.IsKeyUp(Keys.Right))
            {
                move += 0.5f;
                activeAnimationClipIndex = (activeAnimationClipIndex + 1) % Component.SkinnedModel.AnimationClips.Count;
                Component.AnimationController.CrossFade(Component.SkinnedModel.AnimationClips.Values[activeAnimationClipIndex],
                    TimeSpan.FromMilliseconds(300));
            }

            /* if (keyboardState.IsKeyDown(Keys.A))
             {
                 move -= 0.5f;
                 Component.AnimationController.CrossFade(Component.SkinnedModel.AnimationClips.Values[activeAnimationClipIndex],
                      TimeSpan.FromMilliseconds(300));
             }

             else if (keyboardState.IsKeyDown(Keys.D))
             {
                 move += 0.5f;
                 Component.AnimationController.CrossFade(Component.SkinnedModel.AnimationClips.Values[activeAnimationClipIndex],
                      TimeSpan.FromMilliseconds(300));
             }
            */
            else
             {
                 Component.AnimationController.PlayClip(Component.SkinnedModel.AnimationClips.Values[activeAnimationClipIndex]);
             }

            lastKeyboardState = keyboardState;
            lookAtMe.myPosition = new Vector3(lookAtMe.myPosition.X, move, lookAtMe.myPosition.Z);
        }

As the only way I got it working required me to have pressed and released the key, as well as stepping through the animation clips in order, I've decided to do without CrossFade, and use PlayClip instead.

Editor
May 25, 2010 at 1:08 AM

hey steve.

if you use a previous keyboard state and have the if statement to read

"If i am pressing a key and in the last cycle i wasnt pressing a key then perform the action."

using previous keyboard state is only really useful for menus/shooting/jumping, etc. providing of course that they dont require some other sort of functionality.

perhaps you could add a condition to your "if" statement to check if the animation time has elapsed since last cycle and to move and play the animation again.

something like

// in variable declaration:

int animTime;

in // Update Method
 
animTime += 1;

if (keyboardState.IsKeyDown(Keys.A) && animTime == 5)

{

move += 0.5f;

//animation gubbins here

animTime = 0;

}

additionally, why are you moving your character on the Y axis? this is a little non standard :).

hope this helps

 

- bubzy

May 25, 2010 at 1:16 AM
Edited May 25, 2010 at 1:17 AM

with that code, wouldn't the animation play, and the character only move after animTime gets to 5? When does it increment?

The Y axis thing is a holdover from earlier experiments, I've changed it to X axis.

Editor
May 25, 2010 at 1:13 PM

as i said in the first post i made on this thread, i haven't used the animation framework at all, the code i posted was merely a suggestion of a possible implementation :)

but in answer to your question, it would only move every time the variable gets to 5.

the variable would increment every time the game updates which is something like 60 times per second ( i think )

another possibility is to make a boolean value for movement so that its set to true when you press a key and then when a key is released it sets back to false, this could then be bound to a movement routine

if (moveForward)

{

//blah move code here

}

-bubzy