The "Running" animation takes .2 seconds to start playing, which doesn't look good... if you move the character for less than .2 seconds, it looks like they're just skating across the ground without moving their legs (because it's still stuck on the
"Idle" animation, for some reason -- the "Running" animation doesn't start playing until after .2 seconds have passed.)

I love the TransitionToAnimation function, and it looks amazing going from "Running" to "Idle." But it seems like there should be a way to tell it to immediately start playing the "Running" animation -- I would think that would be the default when
you simply call StartAnimation() and not TransitionToAnimation().

So, I'm assuming this is a bug? It doesn't even interpolate the frames between Idle and Running during those .2 seconds, as far as I can tell. It just stays on running for however long the transation time is -- set it to one second and it takes
a whole second to start playing the next animation.

I just checked, and this is still happening even if I change the "running" animation call from StartAnimation("Running") to TransitionToAnimation("Running", 0.0f) -- weird! Will investigate further.

Alex

*edit*

Ok, I seem to have fixed it with some simple noodling around, but I'm not entirely confident with the result. Basically, I had written my player's update loop so StartAnimation("running") only gets called when it's not already the AnimationPlayer's
current animation.

I used the code:

if (Animator.CurrentAnimation != animation)

Animator.StartAnimation(animation);

where Animator is my AnimationPlayer object and animation is a string of the animation to be played.

The rest of the time, I figured it would just run... I didn't want to keep calling it every update loop. And it does work, this way -- until you mix in calls to other animations with TransitionToAnimation, and then the above behavior manifests
itself.

But, calling StartAnimation("Running") makes the running animation play just as I want it to, with no delay between the method call and the animation actually visibly playing. (Even after using TransitionToAnimation("Idle")).

Are we supposed to call StartAnimation() every update frame? StartAnimation is a misleading name if that's the case. I'm looking into what causes this behavior in StartAnimation and in the AnimationPlayer update loop now.

I'm not sure I understand what you're trying to do. Neither of these functions should be called every frame. They're only needed when you want to change what animation is playing.

StartAnimation is for when you want to start an animation immediately. It doesn't look pretty to jerk from one pose to another, but sometimes you can't delay. (I almost never call StartAnimation anymore, except during initialization.)

TransitionToAnimation is for when you want to switch animations, but you want it to look nice. Even having a small transition helps things look smooth.

Would it be useful for me to put together a simple platformer demo to show how I use it? I think I can rip something out of one of my games fairly quickly.

It was a problem in the short method I wrote to wrap StartAnimation().

here's the code that was causing me problems, if you're curious, which is called in the player's update loop:

publicvoid PlayDirectionalAnimation(string animation)
{
animation += Facing.ToString(); //This appends a string equivalent of the Facing value to the animation stringif (Animator.CurrentAnimation != animation) // Condition 1: If the CurrentAnimation being played is not the one we're trying to play
{
Animator.StartAnimation(animation);
}
}

Facing is an enum of type Direction -- it can be Right, Left, Up, or Down

basically I did this so the correct animation could be automatically played (I have four different animations for each action I animate, one in each direction, so the branching statements would get pretty repetitive)

basically, what was happening was that the currentAnimation field was staying as "RunningRight" even though I'd called TransitionToAnimation("IdleRight") -- because the transition was still taking place.

currentAnimation was == "RunningRight" and transitionAnimation was == "IdleRight"

So, when I called the method above, it was waiting until the transition was over before it passed the if statement and called StartAnimation.

I finally got it working with this:

publicvoid PlayDirectionalAnimation(string animation)
{
animation += Facing.ToString(); //This appends a string equivalent of the Facing value to the animation stringif (Animator.CurrentAnimation != animation || Animator.Transitioning) // Condition 1: If the CurrentAnimation being played is not the one we're trying to play//Condition 2: If there's a Transition going on (this will cut off any transition, so the animation we've passed in starts ASAP
{
Animator.TransitionToAnimation(animation, 0.0f); //this is just here to overwrite the Animator.transitionAnimation field
Animator.StartAnimation(animation);
}
}

This was the first thing I wrote that helped me realize what was going on. But I'll have to figure out a better way of only calling TransitionToAnimation() when the player's facing direction or action changes. (I wanted to do it from the update
loop for what I swear is a good reason (:P) but maybe I'll just stick it somewhere else.)

Sorry for the epic pile of confusion that the first post turned into :)

Don't worry about posting the demo for me... the real issue is I need to nail down how I'm doing state management for my creature -- then I'll know the best place to stick animation changes.

Quick question: Why is Update(0) called from StartAnimation() in AnimationPlayer.cs? I tried commenting it out and can't see any effects...

Quick question: Why is Update(0) called from StartAnimation() in AnimationPlayer.cs? I tried commenting it out and can't see any effects...

I'm not 100% sure, but I think that was added to automatically take care of setting the bone transforms in cases where Update isn't being called. (For example, if you're loading an animation to show in an editor, but then you leave it at the default pose.
Without that Update(0), all of the pieces were stacked because they didn't have proper transforms.) The Update(0) is confusing, but better than having a bunch of duplicate code in StartAnimation.

yep, I got up and running with a case statement inside update as well, and I'm planning on switching to a class-based finite state machine, as you did.

I'm planning on making this type of state shared between players and enemies, which should at least somewhat cut down on the sprawling number of classes required for each state. (Player and Enemy are both derived from Creature, which deals with basic
states, movement, and animation).

Thanks for all your help! As you might have suspected from my last post, I've been modifying Demina a lot to twist it to my own ends. I added a deep cloning method to Animation.cs and a Flip() method -- with the DeepClone() method, I create a
separate instance of every animation for each creature in my game. With Flip(), I can create two Right facing animations (by loading one in with the content manager and then cloning it) and then flip one of them so it turns into a left facing animation.
I wanted to do that so I wouldn't have to use a separate SpriteBatch for every creature... all the flipping is done in the Animation file itself, and not at draw time.

The main reason I wanted to create the cloning method, of course, is so I could set each creature's animation to use different textures without adding stuff to the draw call... the Animation instances can be updated once, when a player changes equipment,
and their animation permanently stores that change.

That's the direction I've headed in with Demina so far. Let me know if you want to see the code sometime -- it's not nearly as neat as yours, but I've written a lot of comments. I'll definitely post it when I get bone texture customization fully
working :)

alic44 wrote:I added a deep cloning method to Animation.cs and a Flip() method -- with the DeepClone() method, I create a separate instance of every animation for each creature in my game. With Flip(), I can create two Right facing animations
(by loading one in with the content manager and then cloning it) and then flip one of them so it turns into a left facing animation. I wanted to do that so I wouldn't have to use a separate SpriteBatch for every creature... all the flipping is
done in the Animation file itself, and not at draw time.

I'm curious, why not just use the flipHorizontal and flipVertical options in AnimationPlayer.Draw, instead of copying the animation?

I look forward to seeing what you put together. If you like, toss up a video when you get it all working. :)

I decided not to use the built in flip options because... well, it's a tiny bit convoluted. First of all, I'm making an action rpg style game where the player can move up/down in addition to left/right. This means handling draw order
in one way or another, so that objects further down the screen get drawn on top of objects further up the screen. Personally, I like to use XNA's built-in layerDepth for this. So, I wrote a new draw function for AnimationPlayer that takes in layerDepth.
The problem is, anything being sorted by layerDepth has to be part of the same spriteBatch. Which meant I couldn't use the flipHorizontal function for animations, since that manipulates each animation by making it a separate SpriteBatch.

Then I realized that just by multiplying each bone's position.x and angle by -1 and flipping the texture, each animation would be perfectly mirrored.

I decided that since I wanted to create a system where each creature could use different textures* for the same animations anyway, I might as well create a clone method, rather than trying to manage all this stuff every frame in the draw loop.

That's basically most of what I've done with Demina so far. My goal is to have a simple playable level done in the next month... with some kind of visual character customization. So bug me if you don't see anything pretty soon :)

Obviously that's a really optimistic projection to make for a project I only started a week ago, not to mention my first major game project.
But things are moving along pretty quickly. I really could not be making this much progress without Demina. Thanks again, Jesse.

*note that I'm not actually duplicating the textures with the clone method; just the values that point to which texture to use.