Maddieman's Tutorial on how to animate MP characters

The Example mod that goes with this tutorial is recommended you can download it here

-----------------------------------------------------------------------------
Second Draft 17-9-2003
Contact: Maddieman
This document Copyright 2002-2003 Jonathan Hallier aka Maddieman
Please do not alter or copy any part of this FAQ without my permission.
Please contact me if you want to use this FAQ in another other places.
-----------------------------------------------------------------------------

==VERSION HISTORY==

25th July 2002 - Started Tutorial

27th July 2002 - Finished First Draft

27th July 2002 - Added example mod

17th September 2003 - Republished at Hell's Kitchen, cleaned up a bit, added a few 3ds max updates - but little detail.

---

Special thanks to Zer0 of Zer0mods for initial hosting of this tutorial.

----------------------------------------------------------------------------

==Introduction==

After many requests (well, one actually), I have decided to write a tutorial about creating custom
character animations in Max Payne. It seems that only recently people have shown a sudden interest
in animating Max Payne characters, and there appears to be only a few tutorials on the subject.
The purpose of this tutorial is to inform those who are new to animating, what they will need,
how to get started, and a few basic concepts and techniques. This tutorial is divided into 3 parts,
the first deals with animating, the second deals with exporting animations into MP, and the final
part contains the appendices.

I'll admit that in it's first stage, this tutorial is bit unfriendly looking, and assumes a fair amount
of modding/programming knowledge - I'll be adding pictures later. To be honest, this isn't really a
tutorial, as such. It covers the very basics, but really encourages you to try things out for yourself.
A large section of the tutorial discusses the theory behind more advanced techniques (with examples),
but will not provide a step by step guide.

In addition, this tutorial discusses common problems or issues that I have come across. If you encounter
problems or solve issues that have not been addressed, then post them, or PM me, and I'll try to include
them on the next release.


PART 1: Animating

==1. What you will need==

i) A fully extracted data folder (preferably burnt to CD) - I've already written a tutorial detailing how to do this. Make sure you make a backup of the animations, default_skeleton.txt, Max_payne.txt, and the other text files contained in the skins directory.

ii) Compatible 3D animation package - For the purposes of this tutorial, I will be using Milkshape 3D. It's cheap, easy-ish to use, and compatible with most of the popular PC games, from 'Max Payne' to 'The Sims'. However, I would recommend 3D Studio Max, (since that's the program Remedy used to make MP) if you can afford it. Most of the points outlined in this tutorial will apply to both, though. IMPORTANT NOTE: Actor FX is NOT USED TO ANIMATE CHARACTERS - don't waste your time with it.

iii) A basic understanding of how MP works - i.e. you've have a bash at MaxEd and understand how FSM scripting works. If not, then I suggest you try that first.

==2. Getting started==

I will be brief on this, since there is already another tutorial that explains this in detail.

First go to the preferences and make sure the joint size is set to 0.025

There are 4 easy steps to setting up a Max Payne character for animation.

1. Import Mesh & material data *.KFS
- e.g. Max_Payne_l0.kfs

2. Import skeleton data *.SKD
- e.g. Max_Payne_l0.skd

3. Import default skeleton/pose *.KF2
- e.g. Widepose.k2f --note this is standard pose for all characters.

4. Create a default character *.ms3d
- At this stage your character is ready to animate. To save time though, you may wish to save it (not export it) as a template character. You can then load this character, instead of having to import it with the above steps each time.

Like I said before, the other tutorial covers these stages in a bit more detail.

You now have a choice: Do you create an animation from scratch? Or do you edit an existing one?

For beginners, the best (visual) results will be produced from editing existing ones. However, this tutorial will not make any specific reference to particular animations.

==3. The Basics==

Animation is produced by rapidly displaying still images or frames, at a speed quicker than the eye's perception. Animation in video games is no exception. Characters in MP are animated by positioning multiple 'joints' (limbs, members, etc.) into specific poses (frames). These poses are called the 'Key Frames', and by creating multiple 'Key Frames' animation is produced. The computer will automatically calculate the in-between frames; i.e. the frames required to move the character from 'pose 1' to 'pose 2'. The main benefit of this is that if you have a long animation (100+ frames) you only need to animate about 10 frames, the computer will do the rest for you. Keyframe animation is a fundamental concept in computer animation, and, er, I don't think I explained it very well. Take this example, for instance: Imagine you wanted to animate a character getting up from a chair. There are two major poses that spring to mind, 1: the character sitting down; and 2: the character standing upright. All that you would need to animate is these two frames - the program then calculates the movements or frames needed to move the character from the first position to the second. If you're still in any doubt about it, there are plenty tutorials and articles that will explain frames and keyframes in more detail (Curious Labs poser tutorials are particularly good).

=Animation Mode in Milkshape=

There are two main modes in Milkshape, modelling and animating. Modelling is the default and allows you to change the character mesh and tweak the mapping of textures. Animation mode is, of course, where you create animations for your characters. You can activate animation mode by clicking on the animation button in the bottom right hand corner (provided you have enabled the animation toolbar). Milkshape contains all of the standard animation features that you would expect from a 3D animating package; including play, rewind, move forward/backward 1 frame, jump to next/previous keyframe, etc.


=How Many Frames?=

If you're starting from scratch, the first thing that you need to decide is how many frames your animation will last. Milkshape displays it's animations at 24 frames per second; this can be changed, but I don't recommend it. The average length of animations in MP is about 30 to 50. I don't think there is a limit, but the longest animation I've made lasted 200 frames. Understand that the more frames you have, the smoother the animation will be, at the cost of speed and memory.

=Skeletons and Joint Hierarchy=

Like us, characters in MP have skeletons. Each skeleton is separated into joints which define key areas of the body, such as arms, legs, head, etc. NOTE: Milkshape et al, call these components JOINTS, MP however, refers to them as BONES - Same difference really.

In addition to this, the joints are organised into a hierarchy list. This means that joints lower down on the hierarchy list are affected by joints above them. For example, if you move the upper arm of a character, the lower arm, hand, and gun joints will also move with it. If you move the lower arm, the hand, and gun joints will move, but the upper arm will remain in place. And so on...


There are a few key joints that you will be constantly animating:


Pelvis: This is the central, or spine joint, of the skeleton. It is highest on the hierarchy list and thus, moving it will move every single joint in the skeleton. - Useful for jumping, falling, spinning, etc.

Torso: This affects the upper body of the skeleton - including head, chest/abdomen, and arms.

Upper legs l/r: Controls movement of the thigh - which affects the lower leg, foot, and toe joints, as well.

Lower Legs l/r: Moves all of the joints below the knee - i.e. lower leg, foot, and toe

Upper arm l/r: Ditto, but worth noting that the gun joint is locate on the RIGHT HAND.

Lower arms l/r: Moves all of the joints below the elbow - i.e. forearm, hand, and gun


Head: Essential for giving personality to your animation.

There are a few other joints that are used to make up the Max Payne skeleton, including bones that control the movement of the upper and lower segments of Max's jacket. Most of the time, you wont need to move these unless you're attempting something fancy.


=Setting and Removing Keyframes=

As stated before, animation in MP is made by creating keyframes: specific poses which define the major movements of animation. If you followed the above steps correctly, you should have a 3d model of Max Payne, complete with a stupid grin on his face. Before you do anything, go to the animation menu and disable 'operate on select joint only'. It's worth making the first keyframe the default pose, so click on the drop down menu called 'Animation' and choose: 'set keyframe'. IMPORTANT: If you make any changes to the position of the joints, DON'T FORGET TO SET THE FRAME AS A KEYFRAME!!! If you don't, then you will lose the position data as soon as you move to the next frame. I'm always forgetting this, so you'll thank me later.

The shortcut key for setting keyframes is: <CTRL> + K. This will come in handy later, once your animation is complete. In the troubleshooting section, I will explain why, but for now all you need to know is that it's more convenient. You can also remove a keyframe with <CTRL> + <SHIFT> + K; it's more awkward, but can also be selected from the drop-down menu.


=Positioning Joints=

Ok, this is what it's all about, moving joints to create poses -- a technique referred to as Forward Kinematics. First of all, another important note: For reasons which I can't explain, Milkshape displays a mirror image of what the animation is supposed to look like; i.e. the arms and legs are on the wrong side. Unfortunately, I was completely unaware of this fact until it was too late. There is a feature which is supposed to reverse all of the joint data in Milkshape, however it does not work very well. Just remember that when you export the animation into Max Payne, everything will be reversed back to normal.

In Milkshape, choose the joints tab and select a joint (for the sake of example, choose an upper arm). Now go to the tools tab and select ROTATE. You will now see three boxes, labelled X, Y, and Z. These let you rotate the joint in the said dimension, by x amount of degrees. I normally use a value of 10 degrees, or 5 for fine tuning. If you make a mistake you can use <CTRL>+Z to undo, or use a negative value (-10), to rotate the joint in the opposite direction.

You will have to work out how the joints move on your own, I sometimes feel they move randomly. It's a case of trial and error, but with a bit of patience, you should be able to get them into the desired position.

Once you have your joint in position, set the frame as a keyframe; then select a new joint. Repeat.

When you are happy with your pose, set it as a keyframe, and then save the file. I recommend creating several backups, at regular intervals, in case you seriously mess it up.

Depending on the speed of your animation, you should advance the frames slider by about 3 to 5 frames (10 if you're feeling lucky). Notice that the pose remains intact, meaning you only have to move a few joints. Keep doing this until you're happy with your 'animation'. Don't worry if you have miss-judged how many frames your animation requires: - you can add or delete frames at any point by clicking on the 'frame x of y frames' box.


==4. Advanced Techniques==


=Cut, Copy, Paste, & Deleting keyframes

Not exactly and advanced technique, but if you think the timing is wrong, then you can use these standard tools to move key frames about. Unfortunately, I've yet to discover a way to copy multiple keyframes; right now you'll have to adjust things one frame at a time.


=Squished Limbs Syndrome=

Once you've finished your animation, you may have already tried exporting it into the game. If you exported it correctly, you may notice that the character's joints sometimes squash and stretch out of proportion (sometimes going 2D) in between keyframes. The only logical reason I have that explains this, is that Milkshape and Max Payne calculate the in between frames differently. I guess this is where you're supposed to bring in Actor FX to test the weighting of the character, but never mind about that. The best workaround, is to make each frame a keyframe (remember the note about ctrl-k?); thus Max Payne does not have the opportunity to calculate the in between frames, reducing the margin of error.

UPDATE:

This has nothing to do with Actor FX - it is simply a quirk of exporting animations from Milkshape 3d. The bug will not occur if you export from 3DS Max.


=Move tool and the pelvis joint=

In some instances, it may be necessary to move the entire skeleton. Normally, using the move tool with a joint causes horrific (yet amusing) results. However, if you understand the hierarchy you will be aware that the PELVIS joint moves everything. This allows you to move or rotate the whole figure, which is useful for jumping or falling. I do not recommend using the move tool for walking animations, etc. As a general rule, your animations should remain on the spot, and should not be moved in the x or z direction. If you've downloaded the 'Dodge This' dev kit, you will be undoubtedly aware of how cool the long jump was, yet it didn't work very well. Why? Well, the Morpheus character was moved along the Z axis during the animation, instead of animating him on the spot. Basically the game co-ordinates thought he was in one position, but the animation depicted him in another. This caused numerous collision-detection, camera, and control problems which could have been avoided (not to dis the Dodge this team, what they had finished was awesome).

UPDATE:

As a general rule of thumb, rarely ever should you move the pelvis' postion, except for when a character ducks or falls over. If you want them to jump, use the C_jump() message.


=Camerapaths=

...can't be done in Milkshape (believe me, I've tried!) so forget it.

UPDATE:

See: Camerapaths


=Shoot Dodges, Aiming, and other Blending animations=

These are special types of animations where one animation blends seamlessly into another. Think of the shootdodge move, and how you can twist Max's torso to aim in different directions. There are in fact 8 shootdodge animations, one for each direction, plus another 8 for two handed weapons, such as rifles and shotguns.

One of the most common errors people get is when they try to edit the shooting animation, and get the error:

ERROR: animation x does not have the same amount of frames as animation y

The reason for this, is that the player is supposed to be able to aim in 360 degrees. Therefore, three animations were used: aim up, aim down, aim straight ahead. The Max Payne engine then calculates the positions in between, producing a 360 degree aiming arc. The above error is caused when you edit one of the shooting animations (e.g. shootberetta.kf2) and forget to adjust the others accordingly (shootberetta_up.kf2 and shootberetta_down.kf2).


=Running animations=

I've had numerous problems with editing this animation. I was trying to change it, so that the character sprinted, instead of the sort jog thing that Max does. After the first loop the character stops dead. I think this has to do with number of frames contained in the animation (the default was 40 - my one was reduced to 18). Although the game doesn't crash out with an error, the blending rules may still apply. I'll update this once I find out the solution.

UPDATE:

Looping animations, such as run or walk cycles, can only be exported properly with 3ds Max. In the export box, check "looping". You can also define which frame to loop back to, if you don't want the animation to loop to the very start.


=Inverse Kinematics=

Inverse kinematics is a feature in some 3d animation packages (3ds max) that helps automate the animating process. It works by animating from the bottom of a bone hierarchy, rather than the root, as in FK. This means that if, for example, you lift the character's foot up, their thigh and lower leg will bend in a realistic way. By far the most useful aspect of this is that you can move the pelvis without the enitire figure moving out of position (i.e. the feet say rooted to the ground). Sadly though, Milkshape does not have this feature at the moment.

UPDATE:

3ds Max offers several variations of IK. While I don't have time to go into the details of explaining how to set up IK solvers, if you want a quick IK fix, try using "Interactive IK" under the IK section of the hierarchy tab. Since you're not using a proper IK solver, limbs might move into unnatuaral postions, so make sure you correct these errors as they occur.


=Motion Capture=

Most of the animations in Max Payne 2 were recorded using motion capture, rather than hand animation. Unfortunately, this facility won't be available to the average maddieman.


=3DS MAX= (added 2003)

I'm not going to spend to much time on this, since incredibly in-depth help and tutorial articles come packaged with it. Also, Endo and LJ did a pretty good tutorial over at their site, with pictures and stuff. So instead, I'll keep this short and relevant to Max Payne.

Setting up

You might find that the basic Max Payne skeleton that Remedy provided is a little tricky to work with. Not only is the animation set to loop, there's a grid that must be deleted, he won't render, and a bit of experimentation might produce erratic results (think spinning heads and twisting limbs). Then when you export.... :)

Ok, first off, you might want to consider deleting the grid now, rather than later. You don't have to, but bear in mind that it causes your animations to crash in Max Payne, and can interfere with the IK. You can add another grid later if you want, in fact any object will work just as well.

Viewport Layout

This is more of a personal preference than anything, but I tend to find the following viewport layout the most useful for animating:

It gives quick access to all of the key angles, as well as the all important Perspective viewpoint.

The Dork

Now we're going to set up the character as template for future animating. First off, double click on his pelvis and delete all the key frames for the entire model. Now, click on each bone in turn, and go to motion tab. Under assign controller, you'll see a hierarchy window/box with postion, rotation, and scale listed. Click on Rotation: TCB Rotation, then click on the green arrow button, just above the box. You'll be presented with a list; choose Linear Rotation for now. Do this for all of the bones, except for the jacket ones.

Linear vs TCB

Don't get me wrong here, the TCB controller is better for smooth character animation, but is a lot harder to use. If you've tried animating with it, the chances are that you've already experienced situations where limbs spin or twist 360 degrees in between frames. Using the linear controller is a lot like animating in Milkshape -- it's very rigid, but gets the job done nice and simply. Then you change everything back to TCB to smoothen out the animation.

NB: If you happen to be working with TCB and joints start to twist (indicated by red circular movement paths in the viewpoint), a simple and effective fix is to just click on the offending joint, then switch it to linear, then back to tcb -- problem solved. :)

Exporting

A lot of people have asked me about this, so for simplicity, I decided just to take a snapshot of working export options.

Use this dialogue for exporting animations, models, weapons, and projectiles. For animations though, simply use the above settings. If you're making a looping animation, like a walk, or run cycle - or even a standing animation; then make sure to tick "Loop when finished". Loop interpolation will interpolate (i.e. calculate the in-betweens) the first and last frames of your animation automatically, and Dec. end frame by one removes the last frame. At the top, Loop to frame make the animation return to a specific frame instead of looping to the very start of the animation.

Alright that's 3ds max covered for the time being. For a more extensive coverage of the basics, check out Ghetto Gunz.

***

Well, that's pretty much it for the animation side things. If you're still stuck, feel free to post your questions. If you're trying to make your animations more lifelike, then I suggest you read some of the tutorials for Poser or 3DS Max. While they're a more advanced animation package, the basic concepts still apply.

PART 2: Using Your Animation in Max Payne


A lot of people find this part quite daunting, so I suggest you familiarise yourself with MaxEd and FSM scripting first.

==1. Exporting to *.Kf2 format==


Still here? OK, when you have a finished animation, click file/export/MP models, animations, etc.
Name your file, and don't forget to add the extension .kf2
Choose 'export animation' and hit OK.
This should create your animation.kf2 file which you can use in Max Payne.


==2. Using your animation in Max Payne==

=First timer=

Place your animation in the ..\data\database\skeletons\default_skeleton\anim directory

If you're just starting out, I suggest you try to replace an existing animation (e.g. A death animation, such as death_shotgun_b.kf2). Be sure to make a backup of the original first, though. For compatibility, keep the length of frames identical (otherwise you will get errors).

If you do get errors relating to the amount of frames, and you're not afraid of code, then try the following procedure:

First open the 'default_skeleton.txt' and do a search for the filename of the animation that you replaced.
There are lines of code that begin: "[Message] Frame = x " the number (x) refers to a specific frame in your animation. If the frame does not exist, then you have a choice: either lengthen the animation, or edit the text so that x falls within the number of frames in your animation.

If this still does not work, then leave it for now, it probably employs blending.


Hopefully, that will get you started, and you should be able to experiment a bit, finding out what you can and can't change.


==3. Advanced Techniques==

If you know how to use the *.txt files, then you're better off giving your animation a unique name. This reduces the chances of overwriting something important. Open the text files (usually default_skelelton.txt) and find the animation you want to replace. Rename it, and make sure that any FSM messages which refer to frames are correct.


=Custom Animations=

This has been stressed time and time again, but what the hell: Max Payne offers very little opportunities to add totally new things. Since you don't have access to the source code, you can't implement new features. You can, however, replace what already exists. This is the basic concept of modding, be it textures, skins, levels, weapons, or animations. There are ways around these problems though, as this next example illustrates.

=EXAMPLE=

So, you want to add a new death animation? Fair enough, but after scanning the default_skeleton.txt you've realised that there are only four random death animations, plus about six more specific ones (shotgun deaths, etc.). This is one hell of a restriction, so how do you get around it? Well, each character in Max Payne (including Max) refer to the default_skeleton.txt file to get their default parameters, skeletons, and animation sets. This saves the programmers time, because they do not have to write the code, for loading generic animations (e.g. walking) for each character. However, if you look in the skins folder, you will find a text file for each character. These contain modifiers, which adjust the values set down by the default_skeleton.txt to make the character more unique. These might include how many hitpoints the character has, or how accurate they are; but more importantly, it contains specific animation sets. For example, some of the characters have special 'idle' animations where they use a mobile phone or something. As well as specific animations, you can modify any of the animations originally set down in the default_skeleton.txt. Sticking with our death animation example, this means that one character can have four completely different death animations from another. There are about 45 different characters (excluding redundant ones like the baby, or the invisible one) which means (in theory) you can include...180 different death animations, and that's not even including the shotgun or grenade ones!

Disk space is not an issue either, because the total size of all of the animations comes to around 11MB. Of course, neither Remedy, nor myself, could be bothered to create that many death animations. It also stands, that only around ten of the characters are actually used as enemies in the main game, but the theory is still sound. In fact, it also applies to every type of animation, meaning that characters could have their own style of walking, or shootdodging, etc.

=FSM Scripting=


In the text files, all animations conform to the following syntax:


[Animation] Index = CHARANIM_x; Filename = anim\x.kf2;
[Properties]
{
[Movement] EndPosition = ( 0, 0, 0 ); Rotation = (0,0,0);Middleposition1 = (0,0,0); Middleposition2=(0,0,0);

[Message] Frame = 0; String = "Receiver->Message;";

}

CHARANIM_x

- refers to a specific animation ID (e.g. CHARANIM_WALK) - I don't think these can be changed, since they refer to the source code and how the game plays. For the same reason, I don't think you can make custom ones either.

anim\x.kf2

- where x is the filename. This is the filename which you can change to import your custom animations.

[Movement] EndPosition = ( 0, 0, 0 ); Rotation = (0,0,0); Middleposition1 = ( 0, 0, 0); Middleposition2 = ( 0, 0, 0 );

- Remember the note about the Dodge this long jump? This is the line you need to change to move the character during the animation. (x,y,z) refers to the position where the character will end up, the distance is in meters. Obviously, a value of 0 will not move the character; both negative and positive floating point numbers are accepted. Rotation, will rotate the character. This is not really needed, since you can rotate the character in the animation. Middlepositions are used to tell MP where the character should be at certain points during the animation.


[Message] Frame = 0; String = "Receiver->Message;";


- These are the important lines, they are optional, and you can have as many or as few as you want. If you are not familiar with FSM scripting in MaxEd, then I suggest you do so first. You can send any FSM message, just like in MaxEd. The key difference is that you are editing code for the entire game - not just a specific level. This means that you cannot refer to level objects such as ::startroom::e1, etc. The most common receiver you will use is 'THIS', the character who is being animated. Frame refers to a specific frame in the animation. If the frame does not exist, then MP will take the huff. In addition, I've also found that messages sent on the very last frame also cause errors. As general rule of thumb, don't send any messages on the last frame; finish everything off on the second-to-last one.

Notice that the message is in a text string, enclosed with " " and the line is completed with a semi-colon (;). One of the most common errors you get is 'File.txt does not end!'. The most likely cause of this error, is that you forgot to add the "; at the end of the line. Remember that you are sending a command within a command, which means that not only does the FSM string have to have a semi-colon, but also the 'String =' line as well.


EXAMPLE 1) Flying backwards

Imagine that I have made a new shotgun death animation. I want the enemy to fly back and splat against a wall (think of the Pit fatality in MKII).

Here is the original code:

[Animation] Index = CHARANIM_SHOTGUNDEATH; Filename = anim\death_shotgun_a.kf2;
[Properties]
{

[Movement] EndPosition = ( 0, 0, -3.63855 ); Rotation = (0,0,0); Middleposition1 = ( 0, 0, -2.57104); Middleposition2 = ( 0, 0, -3.28023 );
[Message] Frame = 0; String = "this->C_AnimateTexture( " FACETEXTURE_ID "," FACETEXTURE_DEATH_ID "," 0 ");";
[Message] Frame = 0; String = "this->A_Play3DSound ( enemy, mobster_death, head );";
[Message] Frame = 0; String = "this->c_jump(5);";
[Message] Frame = 0; String = "LeftHandWeapon->WS_Animate(" WEAPONANIM_DROPONDEATH ");";
[Message] Frame = 1; String = "RightHandWeapon->WS_Animate(" WEAPONANIM_DROPONDEATH ");";
[Message] Frame = 22; String = "this->A_Play3DSound ( characters, death_medium, pelvis );";
[Message] Frame = 24; String = "this->P_CreateprojectileToBone( dummy_character_land, 1, torso );";
[Message] Frame = 36; String = "this->P_CreateprojectileToBone( dummy_character_land, 1, torso );";
[Message] Frame = 36; String = "this->A_Play3DSound ( characters, death_medium, pelvis );";
[Message] Frame = 38; String = "this->P_CreateProjectileToBone( blood_dummy, 2, torso );";

}


The movement line explains that the character is going to move -3.63855 meters along the z axis, during the animation. In other words, he is going to fall backwards.

Frame 0: Change the facial expression of the character.
Play death cry, emitted from head
Launch the character vertically, at a speed of 5m/ps
Drop any weapons that might be held in the left hand

Frame 1: The character drops the weapon in his right hand.

Frame 22: Hmm, not sure about this one. A sort of generic death sound

Frame 24/36: Creates a projectile that will cause damage to others or make a mark on the walls/floor

Frame 36: Play a 'thud' sound when the character lands

Frame 38: Spawn blood from the body.


Here is the code for my new animation:

[Animation] Index = CHARANIM_SHOTGUNDEATH; Filename = anim\Splat_death.kf2;
[Properties]
{


[Movement] EndPosition = ( 0, 0, -50); Rotation = (0,0,0);
[Message] Frame = 0; String = "this->C_AnimateTexture( " FACETEXTURE_ID "," FACETEXTURE_DEATH_ID "," 0 ");";
[Message] Frame = 0; String = "this->A_Play3DSound ( enemy, splatter, head );";
[Message] Frame = 0; String = "this->c_jump(5);";
[Message] Frame = 0; String = "LeftHandWeapon->WS_Animate(" WEAPONANIM_DROPONDEATH ");";

[Message] Frame = 1; String = "RightHandWeapon->WS_Animate(" WEAPONANIM_DROPONDEATH ");";
[Message] Frame = 1; String = "this->A_Play3DSound ( camera, swoosh_01, torso );";

[Message] Frame = 15; String = "this->A_Play3DSound ( enemy, generic_fire_death, head );";

[Message] Frame = 22; String = "this->A_Play3DSound ( characters, death_medium, pelvis );";
[Message] Frame = 24; String = "this->P_CreateprojectileToBone( dummy_character_land, 1, torso );";
[Message] Frame = 36; String = "this->P_CreateprojectileToBone( dummy_character_land, 1, torso );";

[Message] Frame = 38; String = "this->P_CreateProjectileToBone( blood_dummy, 2, torso );";

}


I've change it so that the character flies back 50 meters, guarantying that they will hit a wall (despite what you might think - it worked really well).

Frame 0: Change facial expression

Frame 0: Play 'splat' noise on contact

Frame 0: Again, launch the goon into the air

Frame 0: Drop any weapons that might be held in the left hand

Frame 1: The character drops the weapon in his right hand.

Frame 1: Play a swoosh noise, as the character flies backwards

Frame 15: Character hits the wall, arms & legs spread out wide, he screams like a maniac

Frame 22: Again this generic death sound, which I haven't really bothered to investigate

Frame 24/36: Creates a projectile that will cause damage to others or make a mark on the walls/floor

Frame 38: Spawn blood from the body.


The final result is quite, amusing.


EXAMPLE 2) Uncontrolled shooting

I want the character to shoot uncontrollably as he dies.

By now, you should have a fair idea how this FSM stuff works. The following code completely replaces the original.

[Animation] Index = CHARANIM_RANDOMDEATH1; Filename = anim\Death_Fallback_ShootUpwards.kf2;
[Properties]
{

[Movement] EndPosition = (0,0,-2); Rotation = (0,0,0);
[Message] Frame = 0; String = "this->C_AnimateTexture( " FACETEXTURE_ID "," FACETEXTURE_DEATH_ID "," 0 ");";
[Message] Frame = 0; String = "this->A_Play3DSound ( enemy, mobster_death, head );";
[Message] Frame = 0; String = "this->P_CreateProjectileToBone( blood_dummy, 2, torso );";

[Message] Frame = 1; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 2; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 3; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 4; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 6; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 8; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 10; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 13; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 16; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 19; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 22; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";
[Message] Frame = 25; String = "RightHandWeapon->WS_AnimateShooting(" WEAPONANIM_SHOOT "," WEAPONANIM_SHOOTEMPTY ");";


[Message] Frame = 40; String = "this->A_Play3DSound ( characters, death_medium, pelvis );";
[Message] Frame = 46; String = "this->P_CreateprojectileToBone( dummy_character_land, 1, torso );";

[Message] Frame = 45; String ="this->PS_StartEffect ( item_drop, torso );";

[Message] Frame = 45; String = "LeftHandWeapon->WS_Animate(" WEAPONANIM_DROPONDEATH ");";
[Message] Frame = 46; String = "RightHandWeapon->WS_Animate(" WEAPONANIM_DROPONDEATH ");";

}



The first few frames do the usual stuff, change facial expression, make the character scream, etc.

The important frames are 1 to 25. The command is used to fire the weapon in his right hand 12 times. It looks stupid with a shotgun, but fun anyway.

Also notice that the weapon(s) are dropped on frames 45 and 46, not 0.

You may be thinking, that a character who shoots after they've been killed is a little unfair. I have never been hit yet (it's still possible though), this is more for show.

I have included an example mod to go with this tutorial. Feel free to extract it too find out how it works.


Well, that's it for now, I guess. I'm not quite sure how easy it was to follow, but congratulations if you got this far.

Looking forward to seeing your work

-Maddieman

 

==FURTHER READING==

Milkshape 3D - http://www.swissquake.ch/chumbalum-soft/index.html
Importing MP characters into Milkshape - http://www.swissquake.ch/chumbalum-soft/ms3d/tutorials/mp/
PolyGods (some good Milkshape tutorials) - www.PolyGods.com

Aavenr's animation tutorial -- Primarily targeted for MaxEd users, covers the basics quite well.

Ghetto Gunz -- Covers the basics of Max Payne animation with 3ds Max. Lots of pictures, which is nice.

3d Realms Forums:

1000 fps animations

Camerapaths

Enemy Interaction

Adding Projectile Death Animations

 

FIN

 

Home