Qexpo Tutorial Day 7

<-Day 6

Day 8->

Yesterday we got to grips with the animation interface of gmax. Today will give you some more practice with that, tackling a crucial part of animating a monster, getting it to walk. It’ll also expand on the QC stuff we did yesterday. So, open up your animated model from yesterday, go into animation mode, and make sure that the model itself is still frozen.

Select all the bones, and you’ll see the keyframes appear again. We want to start our second animation right after the first one ends, you’d think with means frame 10, but not so. Some people advocate starting a new gmax file for each animation sequence you do, and there are some benefits to this. The main one is that you can make changes that only affect the scope of that sequence by going out of animation mode. In this file that would change things in all frames. The flipside is that doing this denies you the ability to make global changes to anything, even things like the skinmap, without going through and changing every file. Plus it’s a lot more effort to export things, so stick with a single file, at least for this example.

In order to keep the various sequences from affecting one another, you should have keyframes for all your bones at the start and end of each sequence, plus an additional “dummy” keyframe between each scene. This is because the default interpolation isn’t linear, so things can have an effect beyond one keyframe. However, they don’t propogate past two keyframes, so the dummy one creates a buffer between the scenes. We already have them at the start and end of the stand sequence, so drag the slider to frame 10 and right click to create a key frame. Then do the same for frame 11, and it’s here that we start the new animation.


Here’s a breakdown of how the timeline will look once we are done. There will be more keyframes for the walk animations when we’re done.

t7s01Ok, so now we’ve created a keyframe at frame 11, lets set the first pose. We’re going for a fairly steady paced walk, so move the bones to get something like this pose, front leg straight, arms swinging opposite to the legs. Don’t worry that right now the foot isn’t on the ground, we’ll fix it later, just make sure it’s rotated so the sole is parallel to the ground. Go to frame 16, and make the same pose, but swap the front and back legs, and the front and back arms round. Basically it should look like it’s take one pace. Finally, clone all the keys from frame 11 to frame 21.

t7s02If you try the animation out you’ll probably be unimpressed. You can see it’s trying to walk, but it looks much more like it’s just swinging its legs in circles. To improve it, we’re going to first add some more inbetween poses. Go to frame 13 and make the pictured adjustments. The front foot is angled parallel to the ground again, and the back foot/foreleg is raised up/tilted back a little to not go through the ground. Do the same with the legs reversed in frame 18. Preview the animation again and you should see a marked improvement.

t7s03So far, taking a tip from Paul Steed’s very handy animation article: we’ve been working on getting the animation right in one view at a time, starting with the side view. I’d recommend reading the above link either before the rest of this tutorial or after you’ve finished, as Paul Steed is a lot better at this stuff than I am, and having a second opinion on things is often enlightening. So according to him it would make sense to get the feet flat on the ground in the side view, then go to work on the front of the model. So do this, moving the pivot up and down to seat the model on the ground. Notice how in frame 15, the front foot is still not on the ground yet, you should find the same thing happens in frame 20. Clone frame 11 to frame 21 again, so that the whole thing will loop right.

t7s04Time to look at the front view. It looks a bit off, and the problem(thanks again to Mr Steed) is the hips. As you walk you swing your hips forwards in turn with the front leg. This also places the feet closer to the centre line. So, we’re gonna do this for the model. You could just use the pelvis bones for this rotation, but instead I’d say rotate the entire pivot. This way the upper torso will also react to the rotation of the hips, which will look more natural. You should rotate the pivot about 10 degrees in frame 11, and then 20 degrees in the other direction in frame 16(so the overall effect on frame 16 is a rotation of 10 degrees the other way). In these frames you should also rotate the leading foot so that it still points forward, and the upper torso about 5 degrees back, so it still rotates but by less than the waist. The screenshot shows frame 11 after all of these changes. Once you’re happy, clone frame 11 to 21 again.

The walk cycle is now basically done, and it should look fairly good by now. You can add embellishments like making the head face the front the whole time if you so desire. So now we begin the tougher task of getting the walk animation to sync in quake. At the moment the model is “moonwalking”, walking in place, and this is the way we want the final model to be. But we also want to see the model walking regularly, so we can measure how far it will travel, and code that into our monster. So we will spend some time in QMe. Export the model like yesterday, but in the “The Following Frames” box, put “0-8,11-21”. We don’t need frame 9 as it is a duplicate of frame 0, we don’t need 10 as it’s a dummy frame to keep the animations seperate. Why we export frame 21 will be explained later.

Convert the md3 with quark like usual, and open in QMe. Also do all the things we did yesterday, like the eye position at -24 and the movement down by 24 units in all frames.

Margin note 8
This next part, about creating separated animation sequences, is finally something done in QME you can’t do in GMAX. But I still don’t like it. You can use qmdl to automate this kind of animation grouping/naming each time you rebuild the model (examples). You can even deal with the dummy frames from above using qmdl – rather than taking care not to export them, just export all frames and use your qmdl script to delete the dummy ones.

t7i02Find this button on the top toolbar, be sure not to confuse it with the very similar button with black lines above and below the camera, and press it(if it’s not already active). Alternatively select Scenes from the View menu. Now look at the panel on the left hand side. This lists the animation sequences, and at the moment there is only one. All the animation frames are assigned to the default scene “Frame”. Time to change that.

t7s05Expand the list of frames in the scene “Frame”. Then right click on frame 10. You’ll know this is the correct frame, as the animation changes from stand to walk at this frame. Select the highlighted option:Split Scene at Frame. Then rename each of the scenes, stand and walk respectively.

t7s06Save your model now, the changes we’re about to make are for research purposes and should NOT be saved. At the moment you should still have the object panel open, and the scope should be set to “All Scenes”. Change this to “Rest of Scene”. Go to right side view, on the second row of toolbar buttons.

Margin note 9
I don’t mind using QME for this, as it’s just for “research purposes”. But you might find it easier to do this in GMAX the other way round. Rather than creating an running in place animation and working out how far it should move afterwards, animate the skeleton actually walking forwards in GMAX. Once you’re happy, shift the pivot backwards frame-by-frame far enough to re-center the model, and record those movement distances for the walking code.

t7s07The plan now is to move the model forward frame by frame so that the foot on the ground appears to stay still. In other words, you want to remove the moonwalk from the model and make it appear to walk forwards normally. In case you don’t get what I mean by this, I’ve got a copy of a model where I’ve done this.


Let me reiterate, DON’T SAVE YOUR MODEL LIKE THIS. If you compare this model carefully to your own, you may notice that the detail in the x direction seems to have been eroded. The face is the clearest example of this. This is due to the way quake stores vertices, an issue I’ll explain in the next tutorial. Right now, you should record how far you had to move the model each frame in notepad or something, rounded to the nearest whole unit. You want the difference between the previous frame and this one.

Here’s the values I got, yours may vary depending on how your animation looks

frame 1 0
frame 2 7
frame 3 11
frame 4 9
frame 5 2
frame 6 1
frame 7 4
frame 8 13
frame 9 16
frame 10 8
frame 11 5

That done, we go and open the QC file from yesterday. Copy the new version of our model to crusader.mdl in the progs directory.

We want to add a walk sequence, and the frame functions for these will look like

void() crusader_walk1 = [9, crusader_walk2]{ai_walk(5);};

ai_walk is another function we are calling, that walks the monster around the map when it’s not angry at the player, like the patrolling ogres in e1m2. The number in the brackets after ai_walk is the distance it will walk this frame, which is why we spent all that time figuring out how far the animation looks like it walks.

The thing I’m gonna add here is that the 9 is the frame number, but it’s not really intuatively obvious that 9 is the correct number. We’ve only got two animation sequences, so it’s easy to check, but if you had 8 or 10 then it could get confusing very quickly. It would be nice to have a way of calling the frames by names, so you’d only have to get the number right within a given scene. And it just so happens there is. Add the following lines to the very top of crusader.qc

$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10

These lines will be read by the compiler, and the frame names it reads will be assigned numbers in order from 0 onwards, just like the frames in a model are assigned numbers. Now, any time you put the word $walk1, the frame name with a dollar sign preceeding it, the compiler will treat that as the number it was assigned – in this case 9. So we can rewrite our code as

void() crusader_walk1 = [$walk1, crusader_walk2]{ai_walk(5);};

Note that neither the compiler nor the game actually looks at the names of the frames in the model, or the numbers of frames per scene, or anything about the model. It just takes on trust that the list of frames you give it is accurate and in the correct order.

So, here’s the full set of animations for the walk, paste into crusader.qc after the frame definitions, but before void() monster_crusader:

void() crusader_walk1 = [$walk1, crusader_walk2]{ai_walk(5);};
void() crusader_walk2 = [$walk2, crusader_walk3]{ai_walk(7);};
void() crusader_walk3 = [$walk3, crusader_walk4]{ai_walk(11);};
void() crusader_walk4 = [$walk4, crusader_walk5]{ai_walk(9);};
void() crusader_walk5 = [$walk5, crusader_walk6]{ai_walk(2);};
void() crusader_walk6 = [$walk6, crusader_walk7]{ai_walk(1);};
void() crusader_walk7 = [$walk7, crusader_walk8]{ai_walk(4);};
void() crusader_walk8 = [$walk8, crusader_walk9]{ai_walk(13);};
void() crusader_walk9 = [$walk9, crusader_walk10]{ai_walk(16);};
void() crusader_walk10 = [$walk10, crusader_walk1]{ai_walk(8);};

As an exercise you may want to replace the numbered frames in the stand functions with their framenames. It’s not hard.

Note the distances for ai_walk are all mine, fill in your own if they differ. Where did the walk distance for frame 1 come from? Well, from the distance moved in frame 11, we left frame 11 in there so we could see how it loops from 10 back to 1(remember that frame 11 in this sequence is frame 21 in gmax, which is a duplicate of the first keyframe in the walk). You can in fact delete “walk11” from the model now, that’s all we needed it for.

You will also need to make the crusader call the function ai_stand once for it to begin walking. So, replace

void() crusader_stand1 = [0 , crusader_stand2] {};
void() crusader_stand1 = [0 , crusader_stand2] {ai_stand();};
Note that this change will mean the monster will spot you in crusader.bsp straight away, and so freeze. We’re going to use a new map to test it instead.

The final change is like last time to tell the monster crusader_walk1 is the frame/function to use as th_walk. The line should change from
self.th_walk = SUB_Null;
self.th_walk = crusader_walk1;

Ok, that’s it. Compile the mod again, and then grab this new map
Run quake -game crusader, and load up cruswalk.bsp. You’ll need to turn on notarget(type “notarget” in the console and press enter) before he turns around or he’ll spot you and freeze. Once you have notarget on, you can sit back and watch him move around the map.

The last tutorial in the series will look into what the quake model format is like, what problems it causes, and how to get round some of them. It won’t be as formal as all the other tutorials, but should have lots of tips that’ll help you make good Quake models.

<-Day 6

Day 8->


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 )

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.