Setting up short animations (swinging sword, etc)...how? Timers?

Started by
7 comments, last by Kryzon 10 years, 4 months ago

Hey, thanks for checking out the topic.

I'm having a bit of trouble with a few things, but I'll just start by asking about this:

In any entity that has a different animation for each state, I just update and draw the animation depending on the state. Easy enough.

But when it comes to things like casting spells, swinging a sword, etc, I get that I could have these as their own state but I'd rather not do that depending on how specific I decide to make them and I'm not sure how to implement them.

The only idea I have now is to set a timer on a button press and as long as the timer is active, play the animation. I don't really like that solution because now I have to decide how long each animation needs to be played instead of just letting it reach the end of the animation. Although, now that I'm writing this out, maybe I could structure my own animations so that when set to a non-repeating mode, they automatically switch to the appropriate animation...

Anyway, I think my trouble with this mostly comes with my not knowing how to structure some things in something like a game loop. For instance, I couldn't just have a function that fades the screen to black and opens up the battle screen, I have to instead set it to incrementally set it to black each frame and then do things like that? It's all very confusing and if anyone could help me out I'd really appreciate it.

Thanks a lot!

Advertisement

I would do this like a state-stack. Only the animation-state at the top of the stack is updated/rendered, and when it's done, it pops off the top and whatever was under it is automatically the new top-state. Repeating animations don't end, so they shouldn't leave the stack.

Here's a general overview of this idea, as well as a lot of other concepts that might be useful for a new game-programmer: http://gamedevelopment.tutsplus.com/articles/how-to-build-a-jrpg-a-primer-for-game-developers--gamedev-6676

Inspiration from my tea:

"Never wish life were easier. Wish that you were better" -Jim Rohn

soundcloud.com/herwrathmustbedragons

I would do this like a state-stack. Only the animation-state at the top of the stack is updated/rendered, and when it's done, it pops off the top and whatever was under it is automatically the new top-state. Repeating animations don't end, so they shouldn't leave the stack.

Here's a general overview of this idea, as well as a lot of other concepts that might be useful for a new game-programmer: http://gamedevelopment.tutsplus.com/articles/how-to-build-a-jrpg-a-primer-for-game-developers--gamedev-6676

Hey NoAdmiral, thanks a lot. I actually went back and forth with that idea but I definitely need to think about it a little more. That's a much better idea than the callback thing I was thinking of :-)

Also, I've actually been thinking about that article today quite a bit! It was really useful the first time I looked at it and I definitely will be checking that out again.

Thanks again for the reply and advice.

Repeating animations don't end, so they shouldn't leave the stack.

Isn't a walk-cycle a looping animation, but also finite?
It would only play for as long as you hold the movement keys. In this case, it would push in and pop out of the stack sporadically.

I thought about that too, but I think the state-stack idea would work for the short animations the OP is talking about. Animations like walking or idle could just change the base (lowest) state on the stack.

Or idle could be your lowest state, and the walking state could check to see if there is input. If there isn't the appropriate input (you stop holding down the appropriate key), it gets popped. This would also make sense for something like a jumping animation, where it should only apply while your character is in-air. Having the ability to determine if it should continue to play. and pop itself if not would be really valuable to this system.

It's not a perfect idea, though, just the first thing that popped into my mind.

Inspiration from my tea:

"Never wish life were easier. Wish that you were better" -Jim Rohn

soundcloud.com/herwrathmustbedragons

It's not a bad idea, but I do agree that maybe it's not the best way to handle some animations based on state since the player is only ever performing one action at a time. For example, let's say my state stack looks like this: Idle, Walking, SwingingSword (top) - when I'm done with SwingingSword, I may not be holding the movement key down anymore and so I'd immediately be back to Idle anyway. So in that way it makes sense to maybe just keep a vector or array indexed by State to play the animation for simple stuff.

I do think that it works well for what I have in mind, though. I can see how it would be useful in something like turn-based combat where you're idle most of the time save for being attacked and attacking (for a simple one) or maybe a negative status animation, such as kneeling over or something, in which case you'd still want to go back to idle afterwards.
Perhaps a dynamic stack isn't the best abstraction for character animations as it only allows one animation (the top one) to play at a time.
It should be better to use a predefined stack or tree where all the animation hierarchy is already defined, and where simultaneous animation sequences can be played and blended together: Running while casting a spell or slashing with your sword.

So at any moment, you know if a certain animation layer should be playing based on the input that is assigned to it.

If the input for movement is active, you can play the movement layer (the walking animation).
If the input for attacking is active, you can play the attacking layer (the sword slashing or spell casting animations), blending with whatever else is already playing.
If only the input for attacking is active, you can play another attacking animation (attacking while standing your ground, without moving).

A system like this should be quite complex, so if I were to make something like this I would look at how other engines solve this:

- http://docs.unity3d.com/Documentation/Manual/AnimationLayers.html
- http://horde3d.org/docs/html/_usageguide.html#Advanced
- http://www.crystalspace3d.org/docs/online/manual-2.0/Animation-Blending-Trees.html#0
- https://github.com/blackberry/GamePlay/wiki/Animation#animationclips

What format are you using for your engine? Component entity? Inheritance Tree?

For my engine I solve the game state/ loop problem using systems that update components which could be attached to entities...

So for animation.. I have an animation component that can be attached to entities - this component contains a pointer to the actual animation data (each set of animation data can contain a number of animations (run, walk, jump etc) and for each animation there is a map of hashed bone string names to the bone channel data)

This animation component allows you to set the current animation, or animations if blending is enabled.. then the update function of that component checks if an "animate" flag is true and if it is it fills a vector of bone transforms based on the time passed in the update function.. the component also has a flag that tells whether the animation should loop or not... if looping is set to true then as long as animate is true it will keep filling the vector with new final bone transforms.. if looping is false it will set the animate flag to false once the animation has reached its duration

The "AnimationSystem" is then in charge of setting all the necessary variables in the animation components based on scripting/input etc and also in charge of updating the components...

How does an animation component know how long it should play if its not set to loop? Well what I do... is in the AnimationData that the animation component points to I store the duration of the animation in ticks, and then I store the speed of the animation in ticks per second. Then in each bone channel, I store each keyframe quaternion/scaling vector/translating vector with its tick value...

To get a specific bone transform first I get the current "tick" value by doing

currenTick = currentTime*ticksPerSecond

And now you have a tick value that will likely be between two of your bone channel keys... so you use this tick value to do your interpolation between the keys

And you can also test this tick value to see if it is over the animation's duration in ticks... if the animation shouldn't be looping you can check this and set the "animate" flag to false if the currentTick value is > durationInTicks (I actually use the AnimationSystem to do this check and change the value)

Why use ticks? because you can then slow down and speed up an animation (and the duration will change accordingly) simply by changing the "ticksPerSecond" variable and thats it.. a lot easier than storing absolute time values for duration and bone keys etc..

Then handle all animation switching in the AnimationSystem which can switch entitie's animations based on input or based on anything you need really... If you want a button to play cast a spell animation you might check the InputComponent and see if it says to cast a spell... Then you might have an InputSytem that sets the InputComponent values based key presses and rules (ie maybe the player can only cast a spell when it has a target selected) etc...

This works really well for the component type of system...

I'm not sure if this was what you were having a hard time with or not but I hope it helped somehow!

For instance, I couldn't just have a function that fades the screen to black and opens up the battle screen, I have to instead set it to incrementally set it to black each frame and then do things like that? It's all very confusing and if anyone could help me out I'd really appreciate it.

If I'm not mistaken some engines have a generic 'animation controller' class that you can use to animate any property based on a function of time. This controller is handled by an 'animation system' which would be similar to what the poster above discusses.

If you have a fullscreen quadrilateral painted with black, you can assign an animation controller to its alpha property, and you can consider this arrangement as a 'special effect,' handled by your 'special effects manager'.
Whenever your program receives a relevant event, it can activate this special effect by playing its animation controllers. This would perform the screen transitions autonomously.

A clean way to incrementally animate that property you referred to is to have a class dedicated for that, instead of doing it yourself per-frame.

This topic is closed to new replies.

Advertisement