Custom Animation Systems
Submitted:|| 2nd October, 2012
https://dl.dropbox.com/u/110143811/CustomAnimSystem.mfa <- for those who want it quick, a basic example.
MMF2's animation system, while easy to grasp and great for anything simple, just doesn't cut it when you want total control. I'll be explaining a system I use that works perfectly and is very easy to set up. You do not need any extra objects or extensions - just the active object you want to control.
In this article I assume you know the animation editor, how to use alterable values, and a general level of competence with MMF2. Advanced users can make very good use of this, if you don't already have your own system.
All the important aspects of animation in MMF2 are numerical values (which animation, which frame, which direction), and to control them in this system I use the object's Alterable Values. I never need any more than 4 that I rename as such;
- AnimWhich - Which animation - Stopped, walking, shooting, etc and any custom ones you add at the end. As values, they start at 0 for Stopped and count up. Animations you add at the end start at 12.
- AnimFrame - Animation frame - Although listed as Frame 1, Frame 2 etc in the editor, they really start at 0.
- AnimFace - Direction of animation, 0-31. For instance, in a platformer, you'll mostly be using 0 and 16 (right and left)
- AnimCount - This is a counter value that we'll use to control the speed of the animation.
With those 4 values, AnimWhich, AnimFrame, AnimFace and AnimCount, you can now have an 'Always' event (or whatever you prefer - it just needs to be something that updates at the end of each loop) like the following, for whatever object you're controlling with this method.
+ Change animation sequence to AnimWhich(object)
+ Change animation frame to AnimFrame(object)
+ Change direction of animation to AnimFace(object)
That's it. Just have that, or something similar to that, placed far down on the events (below where you actually control these values) and the object will display properly.
Now, controlling the values to make it animate. As it is now, it's all set to 0, so it will be the Stopped animation, first frame, facing right. If you had an event somewhere changing AnimWhich to 2, AnimFrame to 3, and AnimFace to 16, it would be the Running animation, 4th frame, facing left. Simple?
Let's start the ball rolling for actual control by setting up AnimCount.
-AnimCount of (object) > 0
+ Subtract 1 from AnimCount(object)
Now whenever we set AnimCount, it will start counting down every frame back to 0.
Let's say we want a walking animation. As an example, we'll say this walking animation has 4 frames. So in order to display this cycle properly, we want AnimFrame counting up from 0 to 3, and then setting back to 0 to start again.
First you'll want your event that triggers the Walking animation - this depends on your game, but it could be something like 'if object speed is not 0, set animation to walking'. Instead of what you would do before with MMF2's default animation system ('Change animation sequence to Walking'), you want to set the values:
AnimWhich to 1
AnimFrame to 0
AnimFace - this will be set elsewhere, depending on what direction you want your object to face
AnimCount to 8, or whatever you'll be using for the animation's speed. For this example, we'll use 8, since it's a nice average speed.
Note that in this event, you will also want the condition 'AnimWhich(object) <> 1', otherwise it will constantly be setting the important AnimCount value to 8 and it will never count down.
To explain this event basically - When you want your object to look like it's Walking, and it's not already Walking, set up the values so that it can start Walking.
Running this as it is would show the object's first frame of the Walking animation. Now we need it to cycle through the frames.
-AnimWhich(object) = 1
-AnimCount(object) = 0
+ Add 1 to AnimFrame(object)
+ Set AnimCount(object) to 8
^ This will make the AnimFrame count up whenever AnimCount reaches 0
-AnimWhich(object) = 1
-AnimFrame(object) >= 4
+ Set AnimFrame(object) to 0
^ And this sets the AnimFrame back so that it can loop. The animation will constantly cycle as long as the object is 'Walking' (AnimWhich = 1).
Playing around with these values means that you can have the animation loop back from a different frame e.g. in that last event, set AnimFrame to 2 to have the same effect as 'Loop back to' (in the animation editor) with MMF2's default animation. You could also add an event that changes what AnimCount is set to for certain AnimFrame values, so you can have animations with varying speeds. Manipulating values is all there is to it.
Another benefit is that you can easily pause and resume animations by stopping AnimCount from counting down. You could also retain AnimFrame as you switch between animations, say if you had walking animations for your character with his gun raised and lowered and you wanted them to sync up.
Finally I want to mention that this is perfectly compatible with built-in detectors (an article here that is definitely worth a look). As long as the event setting the sequence/frame/direction is at the end, your animations will never be interrupted.
I hope you can put this to good use, thanks for reading!