How to build a "good" animation queuing system

I had done one with jme2, but it didn’t feel clean

I used ints as IDs for input: 1=light attack, 2=heavy attack, 3=equal actionKey (throws: grabs; pickup item) stored them in an arrayList then used that to fill another list with animations, using the values and there positions in the first list to determine which animations to call, then removed that animation from the list once it had been sent to the controller…



the problem I had at that time was figuring out how to limit the size of the lists without producing weird “effects” for the player.

I tried limiting the lists to a fixed number of positions and also tried continuously filling the list while input events were being received or clearing the list if no new inputs were received within a set amount of time since the last event …both ideas never felt “right” and I think that was also the cause of a weird animation looping bug that would happen from time to time.



So how would u go about building one of those dont need code or anything like that just ideas that might help me avoid those little pitfalls



thanks in advance

Here’s a bunch of random thoughts and ideas to help lubricate the thinking proccess… most of which has come from the systems I setup to run the character anination logic in mTheoryGame.



You may need to think about separting your animation logic from your action logic. From a gameplay standpoint, the action of heavy attack or light attack is far more important that the actual animation that get’s played.



I would look at setting up a manager class that stores the queue of actions to execute, and contains the logic for adding and removing actions. An example would be rather than calling arrayList.add() to put a new action in the queue, you would call ActionManager.add(), which would first check to see if that action CAN go on the que (e.g. perhaps you can’t do two light attacks in a row). This class should be responsible for tasks like flushing the queue should an even like player knock down or death occur.



I would concider setting up a data structure to store information about each action/animation, thing’s you may need to know about an action or animation are :

  • animation name - obviously
  • looping
  • execution length - how long this action will take in time, which will probably be the same as your animation length
  • interrupting event - should this action jump to the head of the queue imediately - death animation should probably play right away and not wait for the others.
  • interruptible- can this action be interrupted by others e.g. death animation should not be inerupted but pressing light attack.
  • animation channels - you may need separate queues for the different channels ie legs channel may contain walking and jumping while upper body channel may have attacks queued - often actions will effect both channels
  • chain groups - similar concept to collision groups, perhaps only some actions can be queued together - if your queue contains flying actions, because the player is not on the ground, you don’t want to be adding a ground slide action (NB this sort of logic probably should go here, it’s just an example of different types of groups)
  • max queue time limit - eg if the queue already has ‘queued time limit’ (eg 3000ms) worth of actions then dont add this action. - you may only want to wait <100ms to execute a jump but may happily wait >2000ms before playing an happy dance level up animation.
  • importance weighting - weighting is an extension on the interupting concept, it can get pretty complex but you basically assign an importance to each action, eg death being very high (eg 10) and idle being super low (ie 0), then inside your manager class you can use this weighting to help determin where in the queue an action should go, if at all.
  • should remove on complete - similar to looping, should an action stay in the queue once it’s finished and wait to be replaced eg idle should be at the end of the queue and should never be removed. Falling should not be removed until it is replaced by Landing.



    As far as avoiding wierd behaviour I guess you could look at capping total time allowed in the current queue, by adding together all the execution times of the animations in the current queue.



    There are probably some pretty solid design patterns out there for this kind of stuff, it kind of feels like re inventing the wheel a bit, I would have a look around the likes of gamasurtra for articles on animation queuing.
2 Likes

thanks for this…a lot to take in, and after reading what you wrote I realize that the jme2 concept wasn’t actually that good in fact it was very messy as I had no real management structure just lots of disparate code doing different things to arrive at a single result …in my jme2 game I had stuff all over the place different methods there…a block of code there



as for your point about arraylists are suggesting that I forget them completely and come up with my own data/list management structure(little bit over my head) or just that I should find most effective way of using them



I’ll check out gamasurtra and do other searches to see what I come up with…but yeah I get most of what you say about at least having an actual management system



thanks again