Clean your rig in Maya with the help of Jahirul Amin's latest guide to Maya rigging with over 40 minutes of video tutelage.
to download assets to accompany this tutorial
Maya rigging: Introduction to rigging
Maya rigging: Introduction to rigging a human torso
Maya rigging: Introduction to rigging the neck and the head
Maya rigging: Introduction to rigging the shoulder and the arms
Maya rigging: Introduction to rigging the hands
Maya rigging: Introduction to rigging the legs
Maya rigging: Introduction to rigging the feet
Maya rigging: Introduction to rigging the fingers and thumbs
At this stage, the bulk of the rig is almost complete and soon enough, we'll be able to luxuriate in the joys of skinning (said with heavy sarcasm). However, before doing so, we need to go through and check the rig with a fine-toothed comb. We need to check that we are getting the correct behavior in our rotations, that no joint is flipping out of place and we'll also want to lock and hide any attributes that we do not want the animator to use. Adding to this, we will set the visibility of the FK and IK controls to show themselves when the relevant mode is enabled and also create a main control (the globalSRT) that will allow the animator to place the character in its initial starting position for a shot. Lastly, we will want to hide objects in the Outliner that an animator will not need. This stage may seem slightly mundane, but for me it makes the difference between a finished rig and an unfinished rig.
So, without further ado, let's do some digital housework?
Cleaning the rig
Creating the global SRT control
Before creating the globalSRT control, let's do a little tidying up of the Outliner. Start by selecting l_leg_rig_grp and r_leg_rig_grp and hit Ctrl+G. Rename that new group leg_rig_grp. Now select l_arm_rig_grp and r_arm_rig_grp, group them together and rename that group arm_rig_grp. Next, parent eyes_ctrl_offset, COG_ctrl_offset and spine_doNotTouch_grp under torso_jnt_grp. Then rename torso_jnt_grp to torso_rig_grp as that will make more sense to what that group holds. Now take the following 4 groups: torso_rig_grp, leg_rig_grp, arm_rig_grp and follow_loc_grp and hit Ctrl+G. Rename this new group rig_grp.
Kicking things off by cleaning up the Outliner
Let's now create the globalSRT control. We could create a new shape for this but instead, I am just going to duplicate and re-use a control we already have. So select COG_ctrl and hit Ctrl+D. Then hit Shift+P to un-parent it from its current hierarchy, and then delete all the nodes living underneath it. Rename this control globalSRT_ctrl and then go Modify > Center Pivot. Turn on the viewport grid, hold the X-key on the keyboard to activate Snap to Grid, and snap it to the center of the world. With the control still selected, in the Channel Box, go Edit > Channel Control and set all the Scale attributes as Keyable. When they pop back into the Channel Box, hold down the RMB and go Unlock Selected. Now go Modify > Freeze Transformations, making sure Translate, Rotate and Scale are all active in the options box. To re-scale and re-position the control shape, hit F8, and do so in component mode. To be honest, after all that, it would have been quicker to create a fresh new control! Never mind.
Now take the globalSRT_ctrl and hit Ctrl+G twice. Rename the groups from topmost group globalSRT_ctrl_offset and the next group down globalSRT_ctrl_auto. Next, parent rig_grp under globalSRT_ctrl. The last thing to do is to take both the male_geo_grp and globalSRT_ctrl_offset, group them together and rename this group char_male.
The global_SRT control in place and the rig_grp parented under it in the Outliner
Fixing the scapula and the forearm
Currently, we have a few issues with the scapula and the forearm caused by the rotations of the torso and the wrist respectively. Starting with the scapula, we can fix this by reworking the current expression that we created a while back. So, go Windows > Animation Editors > Expression Editor and look for l_scapula_expr. You may need to change the Select Filer to By Expression Name to bring up the list of current expressions. Edit the expression to read like so and we should be good to go:
l_scapula_ctrl_auto.rotateX = -1 * l_shoulder_ctrl.rotateZ * l_scapula_ctrl.autoScapula;
What this does now, is drive the motion of the scapula through the l_shoulder_ctrl rather than the l_should_jnt. Hit Edit to update the expression and update r_scapula_expr with the following expression:
r_scapula_ctrl_auto.rotateX = -1 * r_shoulder_ctrl.rotateZ * r_scapula_ctrl.autoScapula;
The original scapula setup resulted in the controls going off model
Let's fix the forearm twist now. Again, open up the Expression Editor and edit the l_armTwist_expr to read like so:
l_upperArmTwistA_jnt.rotateY = l_lowerArm_jnt.rotateY * .25
l_upperArmTwistB_jnt.rotateY = l_lowerArm_jnt.rotateY * .5
l_upperArmTwistC_jnt.rotateY = l_lowerArm_jnt.rotateY * .75
l_lowerArmTwistA_jnt.rotateY = l_palm_ctrl.rotateY *.25
l_lowerArmTwistB_jnt.rotateY = l_palm_ctrl.rotateY *.5
l_lowerArmTwistC_jnt.rotateY = l_palm_ctrl.rotateY *.75
And the r_armTwist_expr like so:
r_upperArmTwistA_jnt.rotateY = r_lowerArm_jnt.rotateY * .25
r_upperArmTwistB_jnt.rotateY = r_lowerArm_jnt.rotateY * .5
r_upperArmTwistC_jnt.rotateY = r_lowerArm_jnt.rotateY *
r_lowerArmTwistA_jnt.rotateY = r_palm_ctrl.rotateY *.25
r_lowerArmTwistB_jnt.rotateY = r_palm_ctrl.rotateY *.5
r_lowerArmTwistC_jnt.rotateY = r_palm_ctrl.rotateY *.75
Again, we have just replaced the control to drive the forearm twist as opposed to the joint. Job done.
The last thing I want to do is add a few extra attributes that will allow the animator to turn the automated twist features that we have set up off and on. I'll explain how I set it up for the left arm here but the same approach was used for the right arm and both of the legs. Okay, so start by selecting both l_palm_ctrl and r_palm_ctrl and go Modify > Add Attribute. Create the first attribute with a Long name of upperArmTwist, with a Data Type of Float, in Minimum of 0, a Maximum of 1 and a Default of 0. Using the same values, create a second attribute with a Long name of foreArmTwist. What we want to do now is take our current expression that creates the arm twist and simply multiply it by the new attribute. So, back in the Expression Editor, edit l_armTwist_expr to read like so:
l_upperArmTwistA_jnt.rotateY = l_lowerArm_jnt.rotateY * .25 * l_palm_ctrl.upperArmTwist;
l_upperArmTwistB_jnt.rotateY = l_lowerArm_jnt.rotateY * .5 * l_palm_ctrl.upperArmTwist;
l_upperArmTwistC_jnt.rotateY = l_lowerArm_jnt.rotateY * .75 * l_palm_ctrl.upperArmTwist;
l_lowerArmTwistA_jnt.rotateY = l_palm_ctrl.rotateY *.25 * l_palm_ctrl.foreArmTwist;
l_lowerArmTwistB_jnt.rotateY = l_palm_ctrl.rotateY *.5 * l_palm_ctrl.foreArmTwist;
l_lowerArmTwistC_jnt.rotateY = l_palm_ctrl.rotateY *.75 * l_palm_ctrl.foreArmTwist;
Test it out to make sure it works and repeat the setup for the right arm and the legs. A quick note: as the controls of the IK and the FK legs will not always be visible, I ended up housing the attributes to drive the leg twist on hip_FK_ctrl.
Updating the expressions to get a more desirable behavior and add the ability to turn the automated features off and on