Qexpo Tutorial Day 6

<-Day 5

Day 7->

Yesterday, we went through the process of creating a skeleton for a model and rigging the model with the skeleton, and had got to the stage where the right parts of the model moved with the bones. Now it’s time to make some animations, but the first step is to set the sword to follow the hand of the knight. You’ll want to freeze the model before we start.

t6s01Rotate and move the Sword bone(note NOT the sword itself, from now on we don’t manipulate the model directly) so that the sword sits in the right hand of the knight. With the sword bone still selected, go to the Animation menu, point to constraints and select Link Constraint. Point to a viewport and you’ll see a dotted line extend from the end of the bone(pictured). Click on the “Right Hand” bone and the link is made. Test the constraint out by moving the arm, you’ll see that the sword moves to. Unlike the constraints connecting bones though, you can still move the sword around freely, it’ll just rotate with the arm from wherever it ends up.

t6s02Ok, we need to take gmax into animation mode. Look to the bottom right of the screen and 1: find the large button marked Animate and press it. When in animation mode, changes you make create a keyframe for the change in just that animation frame. The keyframes are interpolated between automatically. For instance, if you rotate an arm 90 degrees in frame 2 from it’s position in frame 0, it will be at 45 degrees in frame 1. When not in animation mode, all changes take place across all frames. Not all changes can create key frames, for instance you can’t animate the skin modifier. Also, some things aren’t sensible to animate, gmax supports animating the UV map, but since quake doesn’t it’s not that useful to us. Almost all the time we will animate bones, which works well. You can also animate meshes directly with the editor, which can be useful for wierd things that aren’t easily done with bones. Once you’ve switched to animation mode, 2: press the “Time Configuration” button.

t6s03The plan here is to set the framerate to 10 FPS. Quake isn’t restricted to 10 FPS animation, but there’s a few good reasons for using it. One is that it is the default for quake monsters, so it makes the QC that bit easier. The second is that the quake model format isn’t that accurate with the positions of vertices, so higher framerates won’t help that much, unless it’s a very fast, large motion like a sword swipe. The third is that most new engines assume 10 fps for interpolation. If your model needs it though, you can go for any speed you like. You don’t even have to have a constant framerate, but it’ll be harder to animate it in the editor. Setting 10 fps here only determines the playback rate in the editor, not in game, but it’ll help us preview the animations. Also set the playback speed to x1.

t6s04The first animation we’re gonna do is a simple idle animation. Notice the bar with numbers along the bottom of the viewports. This is the timeline of frames in the current scene. Drag the grey slider with “0/100” on to go from frame to frame. Nothing changes as you move down the timeline as there’s no keyframes yet. Drag it back to frame 0, where we will make the first pose. The standing pose is alright as it is, but I think it would be more natural with slightly bent legs. Rotate the legs so they arch just a little, making sure the feet are rotated to be flat on the ground. Then move the whole model back onto the ground by moving the pivot. Also rotate the left shoulder and upper arm round a little so the arm hangs down straighter, the right arm can remain raised. The picture shows how this first pose looks.

t6s05Now we’re going to make a keyframe. You may have noticed when you moved bones blue markers appeared on the timeline. These indicate keyframes for one or more of the selected objects. However, we want a keyframe for ALL of the bones here, because it’s the start of the animation sequence. Select all of the bones, and then right click the slider on the timeline. Check that all the boxes are ticked in the dialogue box and ok it.

t6s06Move the slider to frame 3. Here we’ll adjust the pose slightly, so that the torso leans forward and down very slightly, and the head follows. In frame 4, set the arms so that they at the same angle to the ground as frame 0. Both the changes will be interpolated, but the arms will be a little bit slower to react.

t6s07Ok, we’re practically there, but we want the animation to loop, so we’re going to copy the keyframes from frame 0 to frame 9. Select all the bones. Three keyframes should appear, at time 0, 3 and 4. Left click the one at frame 0, then hold down shift and drag it to frame 9. This will clone the key. Then you can try playing the animation back, drag the slider back to 0, find the button indicated in the screencap and press it.

Before we press on, here’s a few general tips for animating with gmax. Use rotations to manipulate the bones. You can move the child bone with the move tool, but this still creates a rotation key in the parent. The problem is that then it’s not clear where the keys are already, which is confusing. The next tip is, where possible make all the keyframes in chronological order. If you insert a keyframe between two other keframes, often you’ll find it interpolates in a wierd way, rotating the long way round and things like that. If this happens, the only fix I know is to delete the later keys and redo them, or undo the creation of the intermediate key. If you do need to put a new key in between, clone a key from a previous frame into the point for the new key, then rotate it into the correct pose.

Ok, now, go to export the model like you’ve done in past tutorials. However, in the box that says “The Following Frames”, fill in 0-8 rather than 0 as we did in previous tutorials. We don’t have to export frame 9, as it is the same pose as frame 0. You will also want to check the box that says “Only Objects Whose Name Start With”, and put a capital O in the box. You don’t want to export the bones themselves in the MD3, and the mesh is called “Object21”. If you’re using your own model, you’ll have to put the name of that in instead. Do the conversion in QuArK as before, it’ll just export the whole animation for you. Then load it up in QMe.

Margin note 7
As I’ve said before, I now recommend doing this kind of scaling and translating in GMAX. Why bother loading a whole new program each time you export when you can get it right first time?

t6s08We have to take a bit more care in QMe, and there are a few things that need doing differently. Set the z component of the eye position to -24, rather than 0. You’ll then also want to move the model down 24 units in all the frames. There’s no need to do this for each frame individually. 1: Get the object panel open, 2: click on the scope dropdown and 3: select “All Scenes” from the list. You can then rotate and translate the model in all the frames, rotate it to face forwards in the front view, and move it so it’s centred with it’s feet on the ground plane in the editor – this should be a translation of 24 units downwards. Then save the model.

To test this model in game, we’re gonna make a mod, and so the rest of this tutorial will be on the QC that governs monsters, but with the focus on the parts that relate to animations. You’ll need a copy of the quake source and a compiler, as well as a map that contains the monster we’re going to create. All these things have been packaged up and can be found here:
http://www.quaketastic.com/files/models/crusader.zip

Extract this to a folder called crusader in your quake directory. We’re going to call the monster we make monster_crusader, just so you know. Rename your knight model to crusader.mdl and put it in the progs directory, then go to the source directory. Make a text file, and rename it to crusader.qc. You can edit qc files in any plain text editor you like, notepad will do for what we’re working on. Then paste the following lines into it.

void() monster_crusader =
{
    if (deathmatch)
    {
        remove(self);
        return;
    }
    precache_model ("progs/crusader.mdl");

    self.solid = SOLID_SLIDEBOX;
    self.movetype = MOVETYPE_STEP;

    setmodel (self, "progs/crusader.mdl");

    setsize (self, '-16 -16 -24', '16 16 40');
    self.health = 150;

    self.th_stand = SUB_Null;
    self.th_walk = SUB_Null;
    self.th_run = SUB_Null;
    self.th_missile = SUB_Null;
    self.th_pain = SUB_Null;
    self.th_die = SUB_Null;

    walkmonster_start ();
};

This is just your basic prototype for a monster with no animations, but we can test it out anyway. Open up the file progs.src in your editor of choice, and add the line
crusader.qc
to the bottom of the file. Now, run frikgui.exe in the same folder and press Recompile. Then run quake with -game crusader, and then type “map crusader” in the console. This is a box map with an entity called monster_crusader on one side. You should see your model in game, stood on the ground nicely, but not moving. You can shoot it, but it won’t do anything. So, time to add the animations.

Open crusader.qc. Each frame for a monster needs a corresponding function, and so here’s the function for the first frame:

void() crusader_stand1 =
{
    self.frame = 0;
    self.nextthink = time + 0.1;
    self.think = crusader_stand2;
    //ai_stand();
}

If you’ve never used QC before, don’t worry, here’s what all the bits mean.

"void() crusader_stand1"
is the name of the function. all the bits of this function lie inside the braces.

"self.frame = 0;"
tells it that it should use the frame with number 0. The frames are numbered from 0 in the order they appear in the mdl/in QMe.

"self.nextthink = time + 0.1;"
tells it when to do the next frame. In this case it’s after 0.1 seconds, which corresponds to 10 fps.

"self.think = crusader_stand2;"
tells it what function to look at when the 0.1 seconds is up, to get the new frame. Note we haven’t written this function yet, so we’ll get an error if we try to compile.

"//ai_stand();"
This line is something a monster usually does when idle, it tells it to run a function that checks for enemies. However, the // means that we have commented this bit out, basically disabled it so the compiler ignores it. We have done this because we don’t want the monster to wake up when it sees us, as it doesn’t have run or attack animations, only stand. It’s left in here for illustrative purposes.

You have to make a function for each frame of your model, so the QC files would be fairly large if you wrote all the functions out in full like this. Luckily, there is a shorthand way, the same code can be written as

void() crusader_stand1 = [0, crusader_stand2] {//ai_stand();

The 0 is for frame 0, crusader_stand2 in the [] is the nextthink function. There is in fact no part of the code that sets the think time to 0.1 seconds, it is implicitly assumed if you use the shorthand that you want the function to set self.think to 0.1 seconds.

So, paste the following into crusader.qc ABOVE what is already there

void() crusader_stand1 = [0 , crusader_stand2] {};
void() crusader_stand2 = [1 , crusader_stand3] {};
void() crusader_stand3 = [2 , crusader_stand4] {};
void() crusader_stand4 = [3 , crusader_stand5] {};
void() crusader_stand5 = [4 , crusader_stand6] {};
void() crusader_stand6 = [5 , crusader_stand7] {};
void() crusader_stand7 = [6 , crusader_stand8] {};
void() crusader_stand8 = [7 , crusader_stand9] {};
void() crusader_stand9 = [8 , crusader_stand1] {};

Notice how similar each one is, that the function names and frames increase by 1 each time, and that the last one loops back to crusader_stand1. Finally, we tell the program that we want it to use crusader_stand1 as the animation function for the stand action. We do this by replacing the line in monster_crusader
self.th_stand = SUB_Null;
with
self.th_stand = crusader_stand1;

Which particular frame you choose to start it off doesn’t matter here, crusader_stand7 would work just as well. Things like attacks really should start from the beginning though, so it’s a convention to start with 1 for everything. So, compile this code with frikgui again, and test it out. It’ll animate! If you shoot it, then it freezes up, but you can see the results of the work before you do that. Next time we’ll look at animating a walk routine in gmax, putting in the code to make it walk, and all that kind of stuff.

<-Day 5

Day 7->

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s