Increasing Rig Functionality
You can animate the basic rig you created in the preceding section as it is, but it would lack efficiency. You would have to manually animate every control, and some skeletons and IK handles would still not have easily selectable control icons associated with them. The backbone joints, for instance, must be selected and animated individually. In this section, you refine the basic rig that you created in the preceding section, and add new controls that make it easier for you to animate your character. This process primarily involves connecting channels using constraints, mathematical expressions, and setting driven keys.
Using Constraints to Create Eye Controls
One of the few body parts of your character that won't be bound to skeletons is the eye geometry. Eyeballs usually don't deform much and need to be able to move around freely in their sockets. Even on a cartoon character that squashes and stretches, the eyeballs should be deformed with a lattice rather than skeletons. This is because skeletons lock the transforms of the geometry bound to them. So if you bind your eyeballs, you won't be able to move them around to make your character look in different directions. Instead, you should parent the eyeballs into your rig hierarchy, and use constraints to make controls for moving your character's eyes around.
Exercise 3.5: Creating Eye Controls
Create a new layer named UnDeformed for all models in your character that won't be deformed. Place your eyeball models on this layer, as well as any other models such as armor, jewelry, hats, and glasses. In addition, all such objects should be made parent to the joint they should followin the same way you parented the polygon reference bones to the appropriate joints. Make sure all the parts of each eyeball can be moved together by parenting them under the white part of the eyeball. Then, to make sure the eyeballs follow the head motion, make the white part of each eye child to the HeadRoot joint.
To make a control icon for the eyeballs, choose Create, NURBS Primitives, Circle q on the top menu bar. In the resulting options box, make sure the circle is facing forward by setting the Normal Axis to Z. Click the Create button, and translate the circle so that it sits directly in front of the character's eyes. Then, create two locators by choosing Create, Locator, and move them so each sits close to the edge of the circle, while also being directly in front of each eyeball. Freeze the circle and locators, and name them EyesLook, LtEyeLook, and RtEyeLook. Make the EyesLook circle the parent of both locators and the child of the Head box.
After you have made the eye controls, you need to constrain the eyeballs to them with an Aim constraint. Do this with the left eye by selecting the LtEyeLook locator, Shift-select the model for the white part of the left eye, and choose Constrain, Aim q. In the Constraint options box, set the Aim Vector based on the center orientation of your eye model. Unless you made your eyeball model with the X-axis pointing forward, the default setting will not work correctly. If you made the eyeball parent so that its center is oriented according to the global axis, where Z is pointing forward, it is the Z-axis that should be constrained. Change the Aim Vector fields so they read 0, 0, 1. This will constrain the Z-axis of the eye model to always point at the locator in front of it. Leave the rest of the fields in their default settings, and click the Add/Remove button. Then constrain the other eyeball to the locator in front of it.
When both eyeballs are constrained, test your controls by translating the circle around. Your character's eyes should track the circle icon (see Figure 3.30). In addition, you can scale and rotate the circle to get more cartoonish effects, such as crossing the eyes or making the eyes wobble. You can even animate the locators themselves to create a wandering-eye effect. In addition, some character setup artists make cone icons in front of their character's eyes to more easily see where the character is looking. Do this by just creating two cones from EP curves, and make each cone child to the white of each eye.
Figure 3.30 Create eye controls by aim-constraining each eyeball to a locator. Manipulating the parent circle icon makes the eyes move around.
Refining the Lower Arms and Hands
Although the basic controls are there, your rig still needs a little work to finish the arms and hands. In a real arm, the rotation of the radius and ulna bones makes the forearm twist. You add two IK joints in your lower arm hierarchy to get closer to how this works. In addition, you set an order to the wrist rotations by creating parented group nodes, and create some finger joints to finish your character's hand.
Exercise 3.6: Adding Forearm, Hand, and Finger Controls
To create a radius and an ulna bone for your character's left arm, use your polygon reference bones as a guide, and draw two skeletons with IK turned on. The radius should go from slightly below where the inside of the arm bends and down to the thumb side of the wrist. The ulna should begin slightly below the elbow and end on the outside of the wrist. After drawing the skeleton, translate and rotate the root joints as needed to place them correctly. Make sure both skeletons are on either side of the main arm skeleton, because the LtArmTurn joint will be the axis they need to turn around (see Figure 3.31). Name the joints for the skeleton that is on the elbow side of the arm LtUlnaRoot and LtUlnaEnd. Name the joints for the skeleton on the other side of the arm LtRadiusRoot and LtRadiusEnd. Name the IK handles LtUlnaIK and LtRadiusIK.
In the hypergraph view, parent the radius and ulna root joints under the LtArmLow joint. This makes the two new skeletons follow the main arm skeleton whenever the left-arm box is moved. Not only do the radius and ulna joints need to move with the arm, they also need to move with the LtArmTurn joint when it rotates in X. To make this work the way it works in your own body, the radius should turn all the way up its axis, whereas the ulna should turn only at the wrist.
Create all the FK finger skeletons for the left hand. Draw the skeletons in the view that enables you to fit them properly into the finger geometry. All the fingers can be four-joint skeletons except the pinky. The pinky should have an extra fifth joint that starts close to the wrist, and represents the pinky metacarpal. The metacarpals for the other three fingers do not require skeletons because they don't move much, and the hand bone can represent them for animation. However, an extra bone for the pinky metacarpal enables you to create a cupping pose on the palm of the hand (see Figure 3.33). The thumb skeleton should also start close to the wrist, but only has four joints. When drawn, rotate and translate the thumb root joint into place. Name the thumb joints LtThumbRoot, LtThumb2, LtThumb3, LtThumbEnd, and then name all the other finger joints appropriately.
After parenting all the finger skeletons, make sure that all the polygon reference bones for the left hand are made child to the appropriate joints. The small bones of the hand, as well as the metacarpals for the index, middle, and ring fingers, can all be made child to the hand root joint. When you are done, try rotating the LtArmTurn joint in X. You should see all the fingers rotating with the wrist.
Figure 3.31 Create a radius and ulna skeleton on each side of the main arm skeleton.
In a real body, the radius bone rotates all the way up its axis when the forearm twists. This is the reason the bicep's muscle, which is attached to the radius bone, elongates and contracts when the forearm is rotated. You can easily do this on your character by making the left radius IK handle child to the LtArmTurn joint. Make the polygon radius bone child to the radius root joint to better see the effect.
If the ulna turned all the way up its axis, however, the joint where the ulna attaches to the elbow would break. To avoid this, you cannot just make its IK handle child to the arm turn joint. Instead, you must filter out the rotation information to use only the translation information, by using a point constraint. Create a locator to do this, and move it right on top of the ulna IK by snapping or constraining, as shown earlier. Name the new locator LtUlnaConstrain.
To finish the forearm, constrain the ulna IK to the LtUlnaConstrain locator by selecting the locator, Shift-select the ulna IK handle, and choose Constrain, Point. Once constrained, make the LtUlnaConstrain locator child to the LtArmTurn joint, and make the LtUlnaIK child to the LtArmLow joint (see Figure 3.32). To see the effect on the ulna, parent the polygon ulna bone under the ulna root joint, and try rotating the LtArmTurn joint in X. Notice the radius turns completely, whereas the ulna only turns at the wrist.
Figure 3.32 To keep the ulna from breaking at the elbow joint, constrain the UlnaIK to a locator that is made child of the arm turn joint.
Figure 3.33 Creating an extra finger joint for the pinky metacarpal enables you to cup the hand.
All the finger roots will be child to the end of the hand joint. Begin this by parenting the thumb root under the LtHandEnd joint. Notice that a bone is drawn going from the end of the hand skeleton to the start of the thumb skeleton. To keep this from happening, with the thumb root selected, group twice. Name the parent group node LtFingerPad1, and the child group node LtFingerPad2. Again, this is just to keep a lot of unnecessary bones from being drawn. Parent all the rest of the finger roots under LtFingerPad2.
Although rotating the LtArmTurn joint in X is the main rotation for the wrist, two other rotations can still be done at the wrist. You obviously do not do these movements by rotating the LtArmTurn joint, but by rotating the hand root joint in Z and Y. Even though you can do both these rotations on the same joint, however, it is a better idea to create two group nodes between the end of the arm and the hand root to do the wrist rotations. Do this by selecting the LtHandRoot joint and group twice. Name the top group node LtWristWave and the bottom group node LtWristShake (see Figure 3.34).
Figure 3.34 Create two group nodes between the end of the arm and the hand's root joint.
When rotating an object in more than one axis, you must consider something called the rotation order. Create a cube, and open the Attribute Editor to see what is set under Rotate Order in the transform node. The default rotation order on an object is always XYZ, which sets the Z-axis as the most important rotation axis, followed by Y and then X. You should set the rotation order so it reflects how you will be animating a particular object and to reduce a rotation problem called Gimbal lock. Gimbal lock occurs when you rotate an object in all three axes until it stops being able to rotate in the least-important axis, as set by its rotation order. You can also get variations on this problem when your object doesn't rotate cleanly in an axis but wobbles in a weird way when you set keyframes.
To reduce the problem of Gimbal lock, character setup artists often set the order of rotation on objects according to how that object usually moves. To see how this works, double-click the Rotation tool to set it to Gimbal mode (see Figure 3.35). This is a special rotation mode that shows you how each axis moves in relation to each other. With your cube set to an XYZ rotation order, try rotating each axis. Notice that rotating the Z-axis rotates all the other axes. Then notice that rotating the Y-axis only rotates Y and X, while the Z stays still. Rotating the X-axis doesn't rotate the X or Z. If you rotate the Y-axis 90 degrees, notice that the local X-axis of the cube is no longer available. This problem is commonly referred to as Gimbal lock. To get a better idea of how rotation order works, try switching the Rotate Order setting, and rotate the cube in Gimbal mode some more. Be aware of the rotation order on your controls when setting up your rig so that you can reduce Gimbal lock occurrences on your controls.
Figure 3.35 Set the rotation tool to Gimbal mode to see how rotation order affects an object.
Another way of setting an order of rotation is through parenting. Separating all the rotations of a control onto different nodes sets the rotation order by making the parent nodes more important than the child nodes. This keeps the rotations from conflicting with each other. For instance, use the two group nodes you created between the end of the arm and the hand joint to separate the wrist rotations. Rotating the LtArmTurn joint already does the most important rotation on the wrist, which twists the hand and forearm. Rotating the LtWristWave node in Z does the next important rotation, making the hand flap up and down. Whereas rotating the LtWristShake node in Y does the least important rotation, which is a small side-to-side rotation (see Figure 3.36). Make sure that the pivot points are correctly placed in the wrist for each rotation. Use insert mode if they need to be adjusted.
Figure 3.36 By doing the hand rotations on separate group nodes, you can reduce the problem of Gimbal lock.
When finished with the left arm, do the same for the right-forearm and right-hand setup. If you try to mirror the entire arm hierarchy to the other side, make sure you first disconnect all polygon reference bones. Using the Joint Mirror command on geometry does not work well. In addition, mirroring a hierarchy often causes the IK to get disconnected on the new hierarchy, so you may have to reset all the IK. Sometimes it is better just to mirror individual skeletons and IK handles as you create them, and then parent them all again on the other side.
Throughout this chapter, you learn several ways to control the channels of objects with the channels of other objects. You have already done this through the use of constraints, such as point and aim constraints. However, these kinds of constraints do not enable you to constrain individual channels of different types, such as constraining a single translation channel to a single rotation channel. To do this, you must use either the Connection Editor, the Expression Editor, or set driven keys.
The most basic way to connect channels is to use the Connection Editor. Open the Connection Editor by choosing Window, General Editors, Connection Editor. You use the Connection Editor by loading the constraining object in the left Outputs side, and loading the object to be constrained in the right Inputs side (see Figure 3.37). The two objects have all their channels listed, and to connect two channels, all you have to do is click them in each window. Keep in mind that the constraint does not go both ways. Only the channel on the object loaded into the right side of the Connection Editor is constrained. Once constrained, the channels have a one-to-one connection based on their values displayed in the channel bar. This kind of connection is pretty simple. To make a more complex connection, where you can vary how the objects are connected, you have to insert utility nodes into the connection.
Figure 3.37 Load two objects in the Connection Editor to connect their channels.
Another way to create connections between channels is by writing mathematical expressions in the Expression Editor, located under Window, Animation Editors. You type your math expressions in the white text field in the lower half of the Expression Editor (see Figure 3.38). Expressions can constrain channels in the exact same way as the Connection Editor, but are written using math signs. Some of the basic signs used are: + (plus), (minus), * (multiply), and / (divide).
Figure 3.38 To connect channels in the Expression Editor, write math expressions in the white text field that specify how to connect the objects.
Object names must be correctly written in each expression, and their channels must be specified. It is a good idea, therefore, to name your objects with short, logical, descriptive, names. Everything in an expression is case sensitive; so make sure you are consistent in how you use capitalization in the names of your objects. All channel names are also case sensitive. In fact, you should be aware that the default names in the channel bar are not how the actual channel names should be written. If you choose Channels, Channel Names on the channel bar, three choices display. The default setting of Nice is not accurate. It capitalizes the first letter in the name, and puts a space between parts of the channel name. Using this syntax in your expressions will give you an error message. Instead, switch the Channel Names setting to either Long or Short (see Figure 3.39). The syntax for both of these settings is accurate, and will work in your expressions. If you want to speed up your workflow by typing less, use the short versions of the channel names. After you create the expression, however, Maya converts the names to the long versions.
Figure 3.39 In the Channel box, change the channel names to either the long or short versions when writing expressions.
The syntax for writing a basic expression that creates a one-to-one constraint between channels is written like this:
ConstrainedObject.channel = ConstrainingObject.channel
Keep in mind that only the object on the left side of the equals sign is constrained. The other object's channels are not affected at all. This kind of expression is extremely simple, but adding some simple math symbols can refine it.
Exercise 3.7: Creating Basic Channel Connections
To get some experience connecting channels, in this exercise you constrain channels using both the Connection Editor and Expression Editor. First, in a new empty scene, create a polygon cube and NURBS sphere under the Create menu. Name the objects Cube and Sphere, and translate the cube in X so that it is not sitting on top of the sphere. Then open the Connection Editor by choosing Window, General Editors, Connection Editor. Select the cube and load it into the left Outputs side of the Connection Editor by clicking the Reload Left button. When loaded, find the channel named Rotate and click the arrow beside it to show the individual rotation channels. Click the Rotate Z channel.
To change the amount that a channel constrains another channel in the Connection Editor, you must use a utility node. Open a hypergraph view, and with both the cube and sphere selected, click the window icon for Input and Output Connections. Then choose Rendering, Create Render Node in the Hypergraph window menu bar. In the Render Node options box, click the Utility tab, and choose the Multiply Divide node under General Utilities (see Figure 3.41). Load the cube into the left Inputs side of the Connection Editor, and select the Multiply Divide node in the hypergraph to load it into the right Outputs side of the Connection Editor. Connect the Rotate Z channel of the cube to the Input1 X channel on the Multiply Divide node. Then load the Multiply Divide node into the left side of the Connection Editor, and load the sphere into the right side. Connect the output of the Multiply Divide node's Output X channel to the inputs of the sphere's Translate Y channel.
Next, select the sphere and load it into the right Inputs side of the Connection Editor by clicking the Reload Right button. To connect the channels between the two objects, click the arrow beside the channel named Translate, and then click Translate Y. Notice in the Channel box that the Y channel for the sphere becomes colored. This means the channel is being constrained (see Figure 3.40). If you select the cube, however, notice that none of the channels are constrained. Rotate the cube in Z to see the sphere move up and down in Y. Also notice that when you rotate the cube in a negative direction, the sphere moves negative in Y. It also moves the exact same amount of grid units that the cube rotates in degrees. This is a one-to-one connection between channels.
Figure 3.40 Connecting two channels in the Connection Editor creates a constraint on the channel of the object in the Inputs field.
The kind of connection you just made between the cube and the sphere has limited uses as it is. In most cases, you would have to adjust this connection either in amount or direction. Notice, for instance, how far the sphere goes when the cube rotates. This is because you are controlling translation, which is based on grid units, with rotation, which is based on degrees. A quarter turn of the cube, which is 45 degrees, makes the sphere translate 45 grid units. Such a distance is going to be way too much for most character controls. Even on a large character, most controls do not move more than a few grid units.
Figure 3.41 In the hypergraph view, create a utility node to adjust a constraint created in the Connection Editor.
If you refresh the hypergraph view, you will see connection arrows going from the cube node to the utility node to the sphere node. Right-click the Multiply Divide node, and choose Attribute Editor. The way the Multiply Divide node works is that the value in Input2 is performed on Input1. So if you set the operation to Divide, for instance, and you set the value of Input2 to 10, the rotation of the cube is divided by 10 (see Figure 3.42). If you then rotate the cube 45 degrees, the sphere translates in the Y-axis only 4.5 grid units, rather than 45 grid units. Try experimenting with other utility nodes, such as the Reverse node, which enables you to reverse the direction of the control.
Figure 3.42 Use the Multiply Divide node to increase or decrease the result of the connected channels.
You can create the same kind of connection between the cube and sphere using a mathematical expression. First, delete the Multiply Divide node in the hypergraph view, which deletes the constraint on the sphere's Translate Y channel. Then open the Expression Editor and type the following in the Expression field:
Sphere.translateY = Cube.rotateZ
After you have written this, click the Create button in the lower-left of the Expression Editor. Select the cube and rotate it in Z to see the sphere move. Notice that the connection is exactly the same as the basic connection that you previously did in the Connection Editor. If the expression disappears from the Expression field, you can locate it again by switching the Select Filter setting from By Object/Attribute Name to By Expression Name, and choose it in the List field (see Figure 3.43). In general, it is better to work in the By Expression Name filter because changing selections on objects will not affect the current expression you are writing. Your new expression should have the default name Expression1. You can then edit the expression to change the name, and adjust how the cube affects the sphere.
Figure 3.43 In the Expression Editor, change the selection filters to edit an expression.
You can do several simple things to fine-tune your expression. For instance, the preceding expression implies the following:
Sphere.translateY = 0 + Cube.rotateZ
This expression reads "the sphere's translation in Y is equal to zero plus the cube's rotation in Z." The zero in the expression represents the start number or the current value in the sphere's Y channel. Change this number so that the expression looks like this:
Sphere.translateY = 5 + Cube.rotateZ
When you click the Edit button in the Expression Editor, notice that the sphere moves 5 units up in Y. Nothing else is changed about the expression except the start position of the sphere. If you change the number to 5, the sphere will be set to 5 in Y as its start position. The other thing you could change is the direction of the constraint. Change the expression to read as follows, and then click the Edit button:
Sphere.translateY = 0 - Cube.rotateZ
When you rotate the cube, notice that the sphere goes in the opposite direction than it did before. Changing the plus to a minus makes the sphere move in a negative direction when the cube rotates in a positive direction, and vice versa. If you want to reduce the amount of the constraint effect, as done previously with the Multiply Divide utility node, use a division symbol like this:
Sphere.translateY = 0 - Cube.rotateZ / 10
Or you could multiply the amount like this:
Sphere.translateY = 0 - Cube.rotateZ * 10
The expression syntax for a basic channel constraint can be summarized as follows:
ConstrainedObject.channel = Default#(Start) +-(Direction) ConstrainingObject.channel */#(Amount)
As you can see, it is relatively easy to create a very specific constraint using mathematical expressions. I personally prefer using expressions to using the Connection Editor with utility nodes to constrain channels. Utility nodes do evaluate a little faster than expressions, however, and some professionals prefer using them for their controls. For the rest of this chapter, you use expressions for doing all constraints that involve math operations. Keep in mind, however, that in most cases you could also use utility nodes and the Connection Editor to do the same kind of constraints. It would just take you a little longer to set up.
Controlling the Backbone with Math Expressions
You may have noticed that the basic FK backbone on your character cannot be selected very easily. To animate it bending, you have to manually select and rotate each one of its three main joints. Because this is not very efficient, you create some controls to make animating the backbone easier. Instead of rotating each joint individually, you use math expressions to constrain the rotation of all the joints to a single control icon. This is much easier for you to select and animate.
Exercise 3.8: Making Basic Backbone Controls
Open the scene that contains the basic character rig you have been building. To create some control icons for rotating the backbone joints, choose Create, NURBS Primitives, Circle q. In the Circle options box, set the Object Normal to Z, and click Create. Scale the circle so that it is slightly larger than the width of your character's torso, and then freeze its transforms. Name this circle BackBend. Then duplicate the BackBend circle, and name it BackBow. Rotate the BackBow circle 90 degrees in Y, and also freeze it. Finally, duplicate the BackBow circle, and name it BackTwist. Rotate the BackTwist circle 90 degrees in Z, and freeze it.
When you have some control icons for the backbone, you can begin connecting channels in the Expression Editor. Keep in mind that your expressions must be based on how the centers of your backbone joints are oriented. If you created your backbone in the front view, Z should be pointed forward, Y to the side, and X oriented toward the next joint in the skeleton. With this orientation, BackBend controls the Z-axis, BackBow controls the Y-axis, and BackTwist controls the X-axis on the joints.
After you have done this, highlight the code again, and use the middle mouse button to drag it to your shelf. This action creates a shelf button to flip your centers around 180 degrees in X. You can open the Shelf Editor to give the button a short name such as RotX. Close the Script Editor, and press Z to undo the preceding rotation. Then, with the center still selected, click your new shelf button to rotate the center exactly 180 degrees in X. You can use the button to rotate any other centers. Then turn off the question mark symbol, and switch back to object mode. When all the centers are oriented correctly, begin connecting your backbone controls by typing the following expression into the Expression Editor:
One last thing you should do is set some rotation limits on your circle icons. A general rule to keep in mind when setting up your rig is to put limits only on the objects you are going to animate directly. So in this case, you should place limits on the circle icons, and not on the joints they control. Right-click the BackBend circle, and choose the Attribute Editor. In the Transform tab named BackBend, click the Limit Information drop-down arrow to see the rotation limit channels. The BackBend circle should rotate only in Z, so click the arrows beside the Min and Max for X and Y, which should set their values to 0. Click the empty boxes to set the limits. Then rotate your BackBend circle positive in X until it is as far as you want your character's backbone to bend to the side, and click the arrow next to Max in the X limits. Copy the Max value, turn on the Min limit, and paste the same value with a negative sign added (see Figure 3.45). In addition, make sure you click all the empty boxes to turn on the limits for each axis. Test your BackBend circle to make sure it rotates only in Z the amount you set.
Follow this same process to set limits on the other two circles. The BackBow circle should rotate only in X, and should rotate more to the front than to the back (see Figure 3.46). The BackTwist circle should rotate only in Y. When you have finished setting the limits, you may do one more thing to the circles. You may want to color the icons to cue the animator how they should be animated. For instance, you could make each circle the color of the channel it should be rotated in. Do this in the Shape tab of the Attribute Editor for each circle, by turning on Enable Overrides in the Object Display, Drawing Overrides section. Adjust the Color slider to set the color. Make BackBend blue, BackBow red, and BackTwist green.
At this point, you should have three circles sitting at the global origin. Select all three circles and group them, naming the parent group node BackControls. In the hypergraph view, parent the BackControls node under the UpperBody icon. You may also want to translate the BackControls to better position them in relation to your character (see Figure 3.44).
Figure 3.44 Place three circle icons around the middle of your character's torso to control the backbone skeletons.
To check how the centers on your backbone joints are oriented, select them and choose Display, Component Display, Local Rotation Axes. Specifically, look to see whether all the centers have the same orientation. If you didn't draw the backbone perfectly straight, some of the centers on the joints may be flipped 180 degrees in X. This occurs whenever you change directions when drawing a skeleton. Because this changes how your expressions affect the joints, it is a good idea to set all the centers so that they have the same orientation. Do this by switching to component mode, and after turning on the question mark (?) symbol, select a center axis that needs to be fixed. Do not type any values in the transform channels to rotate the center. Instead, activate the Rotation tool, and manually rotate the center a little in X. You won't be able to tell how far the center was rotated, but that doesn't matter. Open the Script Editor and find the last line in the gray History field. It should look like this:
rotate r os 23 0 0;
Highlight this line in the Script Editor, and use the middle mouse button to drag it down into the white scripting field. Then change the first number in the code to 180. It should look like this:
rotate r os 180 0 0;
BackRoot.rz = 0 + BackBend.rz;
Name the expression BackRotate and click the Create button. Notice that this expression uses the short versions of the channel names, and ends with a semicolon. The semicolon terminates a line in an expression, and is necessary if you are going to write more than one line. After you create the expression, try rotating the BackBend circle in Z. You should see the first joint of the backbone rotating side to side in Z.
Switch to the Expression Name selection filter if you have not already done so, and click the BackRotate expression to edit it. Highlight the line you just wrote, and copy it by pressing Ctrl+C. Then click the Enter key to go to the next line. Paste the line down by pressing Ctrl+V. Copying and pasting makes it easier for you to create new lines when you need to make similar expressions. Do this twice, and then change the backbone names so that you have the following three lines
BackRoot.rz = 0 + BackBend.rz; Back2.rz = 0 + BackBend.rz; Back3.rz = 0 + BackBend.rz;
After you click the Edit button, try rotating the BackBend circle again. You should see all the backbone joints rotating in the same direction as the circle. This should make the backbone bend in a smooth manner from side to side. To fine-tune this motion, you can divide the effect on some of the joints. The lower part of a real backbone doesn't bend as much as the upper part, so you may want to adjust your expressions in a similar way to the following:
BackRoot.rz = 0 + BackBend.rz / 4; Back2.rz = 0 + BackBend.rz / 3; Back3.rz = 0 + BackBend.rz;
You can divide or multiply your expressions as needed for your character. Keep in mind that you do not have to get the rotations perfect at this stage. Try to get them close to how they should rotate, and then you can fine-tune them after you bind the models to your character, when you can better see the effect of the rotations on the skin. To finish your backbone connections, type expression lines for the rest of your backbone channels, and click the Edit button. Your final expressions will look similar to the following:
BackRoot.rz = 0 + BackBend.rz / 4; Back2.rz = 0 + BackBend.rz / 3; Back3.rz = 0 + BackBend.rz; BackRoot.ry = 0 BackBow.rx / 4; Back2.ry = 0 - BackBow.rx / 3; Back3.ry = 0 - BackBow.rx; BackRoot.rx = 0 + BackTwist.ry / 4; Back2.rx = 0 + BackTwist.ry / 3; Back3.rx = 0 + BackTwist.ry;
Notice that the second set of expressions for the backbone's rotation in Y uses a minus sign rather than a plus sign. If your backbone centers are facing negative rather than positive in Y, you must adjust your expression accordingly. You can start by just using a plus sign, and if your joints are rotating in the opposite direction from your circles, just change the plus sign to a minus sign. Use this trial-and-error method when writing all your expressions.
Figure 3.45 Set the BackBend circle's rotation limits in the Attribute Editor under the Transform tab.
Figure 3.46 Set the limits so that rotating the BackBow circle makes the backbone bend more forward than backward.
Setting Driven Keys for Shoulder Motion
The third main way of connecting channels in Maya is to set driven keys. These are special keys that are not based on the timeline, but instead are based on the connected channels' relationship to each other. The object with the constraining channel is the driver, and the object with the channel constrained is the driven. Setting driven keys has some distinct advantages over other methods for creating basic constraints between channels. Driven keys are easy to set, and are extremely flexible. If you need to do math operations in your controls, however, you will still have to use expressions or the Connection Editor.
To set driven keys, choose Animate, Set Driven Key, Set q. In the Set Driven Key options box, you load the driver and driven, and click the channels you want to connect (see Figure 3.47). Press the Shift key to select multiple driven channels. Once loaded, you manipulate the channels in relation to each other, and click the Key button for each new position. After the keys are set, whenever the driver's channel changes, the driven channel responds.
Figure 3.47 Set driven keys to connect channels by loading objects into the Driver and Driven sections of the Set Driven Key options box.
One main difference between setting driven keys and other connection methods is that driven keys create animation curves that can be edited in the Graph Editor. This enables you to adjust the timing of a constraint in ways that would be difficult using other methods. An expression constraint occurs in a constant manner, for instance, which would be equivalent to a linear animation curve in the Graph Editor. A driven object, however, can respond at a variety of rates to a driver's motion. A driven object can speed up or slow down over the course of a move, which is equivalent to a spline-based animation curve in the Graph Editor (see Figure 3.48).
Figure 3.48 A driven key connection creates spline-based animation curves that you can edit in the Graph Editor.
An additional difference from other constraint methods is that driven objects can have multiple drivers. The driven key's channel is constrained, so you can't set regular animation keys on it manually, or attach another kind of constraint to it. But you can connect additional drivers to it. Being able to connect multiple drivers to a single driven allows you a great amount of flexibility when setting up your character controls. For instance, in the next exercise, you control the raising of your character's individual shoulders with three drivers. This creates automatic shoulder movement based on the position of the arm box and elbow icon, and allows you to use a custom channel for manually controlling the raising of each shoulder.
Exercise 3.9: Setting Driven Keys on the Shoulder
The first driven keys you are going to set make the left shoulder rise automatically when the left-arm box translates in Y. The shoulder in a real body is where the clavicle, scapula, and humerus bones come together. This area rises automatically when the elbow moves above shoulder level. This occurs because there is a notch on the ball joint of the humerus that clicks into place on the clavicle when the arm rises, which then pushes the clavicle up. You set driven keys to make this happen on your character whenever the arm box is raised past the level of the shoulders.
Begin by opening the Set Driven Key options box, and with the left-arm box selected, click the Load Driver button. Choose the Translate Y channel of the arm box in the Driver Channels list. Then load the LtClavicleIK as the driven object, and also choose its Translate Y channel. Before continuing, select the arm box and press the S key to set keys for its default position at frame 1 on the timeline. Keep in mind that this key on the arm box has nothing to do with the driven key connection. You move the arm box around a lot while setting driven keys, and this enables you to easily get the arm back to its default pose when you have finished.
You may have noticed a problem after setting your automatic controls for the left shoulder. After you set driven keys, you cannot manually set translation keys on the clavicle IK. This can still be done, however, by creating a channel that manually drives your left shoulder. The best place to create such a channel is on the Shoulders icon. Select the Shoulders icon and choose Modify, Add Attribute on the top menu bar. In the Add Attribute options box, name the new channel ltShoulder (see Figure 3.50). Make sure that you are using a Float data type, which gives you smooth transitions in your new channel. Then set the Minimum field to 3, the Maximum field to 10, and the Default field to 0. Setting the Numeric Attribute Properties creates the limits on the channel. The reason you set the minimum to a smaller amount than the maximum limit is because a shoulder mostly moves up, rather than down.
The first driven key to set is the default position of the clavicle. Place the arm box on the same level in Y as the clavicle, and click the Key button in the Set Driven Key options box. Then translate the arm box above your character's head until the elbow locks out. Select the clavicle IK and translate it up in Y slightly. The arm should bend a little as the clavicle is raised. Set another driven key. To check the control, translate the arm box up and down to see whether the clavicle moves smoothly in Y (see Figure 3.49). Afterward, click the timeline to force your arm box back into its default position.
Figure 3.49 Set driven keys on the clavicle IK to make the shoulder move up and down when an arm is raised.
Select the elbow arrow icon, and load it as a second driver for the clavicle IK. Choose its translation in Y as the driving channel. To see how this control should affect your character, rotate your own elbow forward and upward, so your palm faces behind you. Notice your clavicle goes up. Before setting driven keys, as with the arm box, press the S key to set a key for the elbow icon's default position. Make sure the elbow icon is directly behind the lower arm joint, and set a driven key. Then raise the elbow icon in Y so the arm rotates about 80 degrees forward. Also raise the clavicle IK a little bit, and set another driven key. When your keys are set, test the control, and then click the timeline to reset your arm controls into their default position. After testing the automatic shoulder controls, remove the keys you set on the arm and elbow controls by selecting their channels in the channel bar, and right-click to break the connections.
Figure 3.50 Create a custom channel on the Shoulders icon to manually drive the clavicle IK up and down.
After you have a left-shoulder channel on your Shoulders icon, you can make it drive the manual translation in Y of your character's clavicle IK. Load the Shoulders icon into the Driver section of the Set Driven Key options box, and choose the new ltShoulder channel. Make sure the driven channel is set to the translation in Y of the left-clavicle IK. Make sure the driver channel is at 0, and the clavicle IK is in its default position, and click Key. Then change the driver channel to 10, raise the clavicle IK in Y, and click Key again. Finally, change the driver channel to 3, and lower the clavicle IK to slightly below its default position, and key it.
When all the driven keys are set, select the ltShoulder channel in the channel bar, use the middle mouse button as a virtual slider, and scrub through the driven keys. As the channel changes, you should see your character's left shoulder moving up and down accordingly. Try out all three of the shoulder controls to see how they work together. Keep in mind that you can set more driven keys to refine this motion. You may want to drive some X translation channels in addition to the Y translation. You may also want to drive the arm root joint's translation to make it rise with the clavicle IK. When the left shoulder is working well, set similar driven keys on the right shoulder.
Creating Additional SDK Controls
In the preceding exercise, you made a custom channel to control the translation in Y of the clavicle IK. Doing this enabled you to set manual translation keys on a channel that was already being controlled by driven keys. Even if there were no other driven keys on the clavicle IK, however, creating a custom channel on the Shoulders node would still be desirable.
You may have noticed that some objects in your rig do not have easily selectable controls. If you made icons for every control in your character, your interface would soon get cluttered. Some objects in your rig that are difficult to select are the individual shoulder IK handles, the arm turn joints, wrist pivots, finger joints, and the jaw joint. The best place to put control channels for these objects is on the closest main control icon. For instance, arm, finger, and hand channels can be placed on the appropriate arm box, and jaw controls can be placed on the Head box. You can then connect all these channels to the objects they should control by setting driven keys.
Exercise 3.10: Setting Driven Keys on Other Parts of the Body
Another automatic motion you can add to your shoulder is movement in Z when the arm moves forward and backward. This involves the Z translation of the clavicle IK, and some X and Z translation of the scapula root joint. Load the translation in Z of the arm box as driver, and load the Z translation of the clavicle IK as driven. Set driven keys with the arm box out in front of your character, and back behind your character about 30 degrees.
You can add several channels to each arm box to control your character's forearms, hands, and fingers. Begin by making three custom channels on the left-arm box named wristTurn, handWave, and handShake. Set the minimum for these channels to 10, and the maximum to 10. Open the Set Driven Key option box and load the wristTurn channel of the arm box as the driver. Load the LtArmTurn joint's X rotation channel as driven. Then set a driven key with the arm turn joint in its default position, and the wristTurn channel at 0. Then change the channel to 10, rotate the arm turn joint forward in X about 45 degrees, and set a driven key. Keep in mind that the degree to which a real forearm turns is very little. Most of the turning on the arm occurs from the shoulder, and should be done by translating the elbow icons. Change the wristTurn channel to 10, rotate the arm turn joint backward in X about 100 degrees, and set a key. Scrub the wristTurn channel to see the forearm turning.
Create a few custom channels on the Head box to move the jaw and neck. Name the channels jawOpen, jawGrind, jawJut, neckBend, and neckTilt. The jawOpen channel should rotate the jaw joint in Z so the mouth opens and closes. The jawGrind and jawJut channels should translate the jaw from side to side, and translate the jaw forward and backward. Set the minimum and maximum values to the appropriate values to achieve these movements. Then load the jaw joint in as driven, and key the appropriate channels. The neckBend and neckTilt channels should make the NeckRoot joint rotate side to side and forward and backward.
Driving the clavicle IK in Z rotates the scapula a little because the scapula IK is child to the clavicle IK. When a real arm moves forward and backward, however, the scapula actually floats around the rib cage to some degree. You can best experience this motion by stretching both your arms backward, and then notice how your scapulas press together. To make the scapula translate around the rib cage, load the scapula root joint as driven, with the translation in Z of the arm box still as the driver. Hold down the Ctrl key to select the translation in X and Z of the scapula root joint. Then key the translations of the scapula to make it move in a small arc around the rib cage as the arm box moves forward and backward (see Figure 3.51).
Figure 3.51 Also use driven keys to make the scapula translate around the rib cage in an arc when the arm is moved forward and backward.
Next, use the same method to make the other two custom channels on the arm box drive the two group nodes that are parent to the hand joint. Make the handWave channel drive the up-and-down rotation of the LtWristWave node, and the handShake channel drive the side-to-side rotation of the LtWristShake node. Depending on which way the hands of your character are facing, the two driven channels will probably be Z and Y. Keep in mind when setting driven keys that the wave rotation is larger than the shake rotation. After you have all the driven keys set, you should be able to use the three custom channels to place your character's hand into any pose.
To set driven keys for the fingers, create five channels on the arm box named indexFinger, midFinger, ringFinger, pinkyFinger, and thumb (see Figure 3.52). Because fingers only go in one direction, you may not need much of a minimum value on the channels. This depends on whether your character's fingers are straight or relaxed in its default pose. If they are relaxed, you will have to put a minimum value that is large enough to straighten them out. Set the maximum value for each finger channel to 10.
Figure 3.52 Create several custom channels on each arm box to control the forearm, hand, and finger motions.
Then load the indexFinger channel of the arm box as the driver. Hold down the Shift key in the hypergraph view to select LtIndexRoot, LtIndex2, and LtIndex3, and then load all three index finger joints in as the driven. Select with the Shift key all the finger joints in the Set Driven Key options box, and choose their rotation in Z as the driven channel. Set a key in their default position, with the driving channel at 0. Then change the driving channel to 10, rotate all the index finger joints into a closed position using the Up and Down Arrow keys to move through the finger hierarchy, and set another key. Set the driving channel to the minimum value, rotate all the index finger joints until they are straight, and set a final key. Repeat this process with all the finger joints. In addition, you can create fingerClosed and fingerSpread channels on the arm box that drives all the fingers at once. The fingerClosed channel should drive the Z rotations of all the finger joints, and the fingerSpread should drive the Y rotations of the finger root joints to spread the fingers away from each other.
Making a Hands-Follow Switch
Currently your hands should be following your backbone when it moves. The reason this occurs is because the arm boxes are child to BackPad2. If your hands were parented under the UpperBody icon, however, they would move with the torso, and not move with the backbone. At times while animating, both of these parenting solutions will prove useful. If your character was pushing a heavy object, for instance, it would be easier to animate if the hands did not move with the backbone (see Figure 3.53). On the other hand, if the character was walking, it would be easier to animate if the hands follow the backbone. Actually, both these solutions are possible if you use constraints.
Figure 3.53 It is easier to make your character push a heavy object if the hands do not follow the backbone.
Exercise 3.11: Using Constraints to Create a Hands-Follow Switch
Create a locator named Hands, and make the Hands locator the parent of both arm boxes. Create two other locators named BackFollow and TorsoFollow. Make sure all three locators are sitting directly on top of each other. The BackFollow locator should be the child of BackPad2, and the TorsoFollow locator should be the child of the UpperBody icon. The trick to creating a switch for how the arms follow the backbone is to create two constraints that make the Hands locator switch between following BackFollow and TorsoFollow.
To create a way of switching the constraints, you must create a custom channel that will be connected to the weight channels of each constraint. Do this by selecting the UpperBody icon, and choose Modify, Add Attribute. Create a custom channel called armsSwitch, with limits from 0 to 1, and a default value of 0. You can use the Connection Editor, expressions, or set driven keys to create a connection between the armsSwitch channel and the constraint channels.
Select the BackFollow locator, Shift-select the Hands locator, and choose Constraint, Point on the top menu bar. With both still selected, go to the Constraint menu again and choose Orient. This places both a point and orient constraint on the Hands locator. Select the TorsoFollow locator, Shift-select the Hands locator again, and create both point and orient constraints. If you select the Hands locator, you should see two point constraints and two orient constraints in the Inputs section of the Channel box (see Figure 3.54). Having these two constraints is the key to creating a switch. Notice that each constraint has a weighting that goes from 0 to 1. When the channel is at 0, the constraint is turned off, and when it is at 1, the constraint is fully turned on.
Figure 3.54 Use a custom channel to control the weight channels of two point constraints to make the arms appear to switch parents.
The armsSwitch channel should make one of the constraint channels follow it exactly, and make the other constraint channel follow it in the opposite direction. This has the effect of turning one constraint on, while the other constraint turns off. For example, you can do this with an expression like this:
Hands pointConstraint1.BackFollowW0 = 1 - UpperBody.armsSwitch; Hands pointConstraint1.TorsoFollowW1= 0 + UpperBody.armsSwitch; Hands orientConstraint1.BackFollowW0= 1 - UpperBody.armsSwitch; Hands orientConstraint1.TorsoFollowW1= 0 + UpperBody.armsSwitch;
When the channels are constrained, try rotating the BackBend circle, and then scrub the armsSwitch channel on the UpperBody icon. You should see your hands smoothly switching between staying still and following the backbone. The hands should still follow the upper body, even when they don't follow the backbone. If you didn't want the hands to follow anything, you would do the same process, only using a locator that is child to the Rig node, rather than the UpperBody node.