MART Term 1, Lecture 9
Advanced Rigging and Character Controls

Advanced Rigging

Today we are going to take the simple rig that we made last week, and make it into a better rig that's more effective and easier to control. Open the file

rigging-start.ma

[screenshot: MART_T1L09_html_m62e4e5f2]You should find a couple of minor differences: our character has three joints in his feet, so that his feet bend more like real feet, and he has a tail. This is so that I can show you different methods to control this kind of chain.

Let's start by sorting out our pole vectors. Last week I showed you how to use the t key to let you position the knee of the character. Though this method is usually very effective, it is sometimes useful to be able to say "point the knee towards X" (where X is a separate object). Let's look at how to do that now.

Pole Vector Constraints

Traditionally, character rigs are controlled using locators: we move locators around, rotate them and scale them in order to get different parts of the rig to move. This can get very confusing: all locators look the same, so it is necessary to remember the position of the locator that controls the parameter you want to change. Another option is to make all of the controls look different by using curves (which do not render) or surfaces (which we set not to render). I shall try to use different objects to help us to remember which object does what.

Make two objects for the left and right knees to look at: I'm going to use the Create → Text menu item to make an L and an R out of curves.

In order to set a pole vector constraint, first select the object that the pole vector points towards, and then the ikHandle of the IK chain. Then go to the Animate set of menus and pick Constrain → Pole Vector. You should find now that when you translate the L, the left leg rotates to point towards it. Do this with both legs.

Aim Constraints

[screenshot: MART_T1L09_html_m663509d]Now let's try creating a "look-at" constraint: we'll make our character's head point towards a particular object. First, let's give our character a "head" so that we can tell when it's pointing in the right direction. I'm going to use a cone, because we have to know which direction it is pointing. Once you've created something, parent it to the neck joint (right).

Now create an object that you want your character to look at. In order to aid remembering which object does what, I'm going to use a curve to sketch an eye (very quickly). Move the object away from the "face".

[screenshot: MART_T1L09_html_m7f7c7f0b]Now we want to set an aim constraint: this constrains the rotation of an object so that it always points towards another. Select the object that you are constraining to (the eye in my case), then the object you are constraining (the neck joint), and click on Constrain → Aim. This will constrain the joint, but by default it will point the top of the head towards the eye (left). Change the three offset values so that the head is pointing in the correct direction. A good way to do this would be to adjust them using virtual sliders (hint: do the z first, then the x).

You should now find the the head of our rig will always looks towards the look-at constraint. You can keyframe the translation of the object to make the character look around.

Adjusting The Root

We currently have a single joint as the COG of our rig. This works, but if we want to give just the upper body a twist of the hips, we can't do it. What would be better is if we could twist the upper and lower body separately and easily. We do this by adding objects into our hierarchy.

Let's make a wish-list:

[screenshot: MART_T1L09_html_m63ea764a]The solution involves some substantial changes to the hierarchy. Here is a before and after screenshot of the outliner.

[screenshot: MART_T1L09_html_1d3b6ba1]I effected most of these changes by moving things around in the hierarchy. I inserted a new joint above the (previous) COG: the new joint became HipsUpper and the old COG became HipsLower. I made a new COG (NURBS circle) and a GlobalSRT (polygon cube).

[screenshot: MART_T1L09_html_m4766e4d3]The COG area of the character itself is shown here. We now have a circle which we can grab easily which moves the character without the ikHandles, and a polygon cube which moves it with them. Notice that our skeleton doesn't join in the middle: this is because our COG is now a curve and not a joint. This probably doesn't matter: if you remember what I said last week, the bones only exist to indicate that one joint is parented to another joint. Have a go now at rotating both halves of the body separately.

Connections, Expressions, and Driven Keys

[screenshot: MART_T1L09_html_m170c4e65]Lets look at the tail. We want to be able to easily manipulate the whole tail, rather than having to rotate each joint individually. There are three main ways to do this, as the heading suggests, all of them involve having a control object which alters all of the joints' rotations at once. I'm going to draw a little arrow so that it's clear what it does (right). Don't forget to centre the pivot as well.

[screenshot: MART_T1L09_html_1d4ff379]The first method we're going to try is by adding connections: we're going to set the rotations of all the joints to be exactly the same as the rotation of the arrow. Bring up the connection editor by clicking on Window → General Editors → Connection Editor, and make it Always On Top. We're going to be connecting the x rotation of the arrow to the z rotation of the joints. Select the arrow, and click the Reload Left button. Now select all of the joints (in the outliner might be easiest), and click Reload Right. Find the Rotate X parameter in the left box, and all of the Rotate Z parameters in the right, and select them all (you'll have to expand the Rotate input to get at Rotate Z).

Now try rotating the arrow: as you see, it works quite well in this situation. Lets look at other ways to get the same effect. Let's try getting the same effect but over a longer rotation, in order to get more control. Select all of the bones, select rotateZ in the channel box, and select Break Connections from the pop-up menu. Now open up the expression editor. For each of the tail joints, set the expression to be

TailJoint.rotateZ = TailControl.rotateX*0.5

Now try rotating the tail control, and notice that the winding of the tail happens more slowly. This could not have been accomplished via direct connection, but it took AGES to do. Let's try doing it a different way, using driven keys.

A driven key consists of a driver and a driven. A single parameter is loaded as the driver, and this, as the name suggests, drives the animation of the driven parameters. Normally, when we set standard animation keys, time is our driver: we say, for example, "at frame 10, the ball is on the floor". With driven keys, we could say, for example, "when the door is open, the ball is on the floor". Thus, in this circumstance, we want to say, "when the rotation of TailControl is 0, the tail is in its relaxed position".

[screenshot: MART_T1L09_html_ffef8ec]With nothing selected, go to Animate → Set Driven Key → Set ❐. Make the ensuing window Always On Top. Select TailControl, then click Load Driver; select all of the tail joints, and click Load Driven. Go through and find the correct parameters: rotateX for the driver, and rotateZ for the driven. Now we are ready to key them.

Remember when we keyframe things normally, we have to change the time first, then move the object, then keyframe it. The same is true with driven keys, except that time is not our driver: we have to change the driver first, then the driven, then set the key. So press Key first (to set the tail to be this shape when the control is not rotated at all), then rotate the control, re-shape the tail, and press Key. Do this as many times as you like, then try rotating the control and see how it works. This allows us to control the shape of the tail much more easily than with expressions (the same thing is possible using expressions, but very difficult). This method is very useful for controlling complete sets of fingers with a single control.

Footroll

Our method for controlling the feet leaves a lot to be desired. When a person walks, their toe is the last part of their foot to leave the ground. At the moment, in order to animate this, we would have to move the ikHandle up and rotate the foot joints so that the toe is back in the same place as it was before. It would be better if we could rotate the foot at the toe. Even better, if we could rotate the foot at the toe or at the heel. Or even better, if we could decide whether to rotate at the toe, the heel or the ball of the foot. Is this asking a little too much? Not with a little hierarchy shenanigans.

[screenshot: MART_T1L09_html_2f5675c8]First of all, we want to get four control objects: one to control the heel, one for the ball, one for the toe, and one for the ankle; rename them as such. We also want to have another IK chain, going from the ankle to the toe.

Now we want to parent the ikHandles to the correct control objects: the handle at the ankle should be parented to the ankleControl; the handle at the toe to the toeControl.

As for the controls themselves, the heelControl should be at the top of the hierarchy (this is the one we shall generally use for translating the foot), then the toeControl, then ballControl, then the ankleControl.

The ankleControl is not very useful (I usually work with it hidden), but try translating the ankleControl and rotating all of the others. You should find that the foot is now very easy to control.

Essentially we have created a second hierarchical system: in addition to our joint chain, which travels down the leg from knee to toe, we now also have a chain (courtesy of our control objects) which travels from toe up to the ankle that we use to control the IK handles. If, at this stage, you don't understand why it works, don't worry. When you eventually do, the rest of rigging will drop neatly into place.