Begin by connecting the joints that will help the arm's twisting deformations
look more believable.
-
Using the Connection Editor, connect the wristJoint.rotateX attribute
to control the wristTwistHelper.rotateX attribute (highlighting in
the Connection Editor, just like in the last example). Then connect
the shoulderJoint.rotateX attribute to control the shoulderTwistHelper.rotateX
attribute using the same method (see Figure 17.49).

Figure 17.49
Connecting the joints that will help the arm's twisting deformations.
Next, you will create a standard IK control for the arm, which will
enable the animator to control the twisting of the shoulder and the
orientation that the elbow is pointing. You will pole vector–constrain
the wrist's IK handle onto a locator that is situated behind the character,
which can be grabbed and translated around to control the arm's orientation.
-
Create a locator (click Create, Locator) and rename it armPoleVectorConstraint.
Now, with the Move tool activated, hold down the v key (Point Snap
mode) on the keyboard and, holding down the middle mouse button, click
and drag the locator toward the shoulderJoint until it snaps into
place on top of the shoulderJoint. Then, no longer holding the v key,
translate it backward a few units behind the character.
-
Make the armPoleVectorConstraint locator a child of the connectToSpine
node by selecting the armPoleVectorConstraint and then the connectToSpine;
then hit the p key on your keyboard.
-
Select the armPoleVectorConstraint locator and Shift-click the armWrist_IkControl
node to add it to the selection. Create a pole vector constraint by
using the menu command Constrain, Pole Vector.
-
Select the armPoleVectorConstraint locator and perform Modify, Freeze
Transformations to zero the locator's transforms.
Next, you will create the extra controls that will allow the hand
to be "planted" or stuck on any object. For example, if the character
needs to lean his hand against the wall, grab onto a pole and swing
around on it, or even just hold on to a steering wheel, this setup
will easily allow for it.
The way you'll accomplish this is very simple indeed. First, you'll
create two locators and parent them under the same group as the armWrist_IkControl.
Then you will create weighted point and orient constraints from these
two locators onto the armWrist_IkControl node. Finally, you will add
an attribute that will control the weight of the constraints that
were added, to determine which locator the IK handle gets constrained
onto. Let's get started.
-
First, create two locators. Rename one locator plantIkHand. Rename
the other locator freeIkHand.
-
With the Move tool activated, hold down the v key (Point Snap mode)
on the keyboard and, holding down the middle mouse button, click and
drag both locators toward the wrist's armWrist_IkControl in the 3D
view port until they snap into place directly on top of the armWrist_IkControl.
-
Next, parent both the plantIkHand and freeIkHand locators under the
same parent as the armWrist_IkControl node (the scapulaClavicle_IkControl)
by selecting the two locators and Shift+selecting the scapulaClavicle_IkControl
to add it to the selection last; then hit the p key on your keyboard.
Next, you will create an empty "null" transform node that you'll
use to parent the IK handle and both locators under so that they are
in the same orientation and position as the wristJoint node. You can
then orient-constrain the wrist to the IK handle without changing
the current orientation of the wrist.
-
Create the null transform by first being sure that nothing is selected
and then hitting the Ctrl+g keyboard combination.
-
With the new null node created, point-snap it to the wristJoint node
using the Snap mode of the Move tool by holding down the v key while
clicking and dragging with the middle mouse button held down. Zero
the null node's transforms by selecting it and performing Modify,
Freeze Transformations.
To put this null node into the same orientation as the wristJoint,
you will point- and orient-constrain it and immediately delete these
constraints by executing a single line of MEL code supplied in the
next step.
-
A quick and easy way to do this is to execute the following MEL command
in the command line (first select the wristJoint node and Shift+select
the null node to add to the selection). Now execute the following
bit of tricky code (which actually creates constraints for you and
then automatically deletes them immediately afterward so that they
will line up your nodes but not keep them controlled via a constraint
relationship—all at the same time):
delete 'orientConstraint'; delete 'pointConstraint';
-
Rename the null node to be called wristTransformCompensation. Parent
it under the same node as the armWrist_IkControl IK handle and plantIkHand
and freeIkHand locators by first selecting the wristTransformCompensation,
Shift+selecting the clavicleShoulder_IkControl node, and hitting the
p key on the keyboard.
The null transform is now in the same orientation space as the wristJoint,
but it will travel correctly under the clavicleShoulder_IkControl
IK handle node. You will now make this new wristTransformCompensation
null node the parent of the armWrist_IkControl IK handle and plantIkHand
and freeIkHand locators.
-
Select all three of these nodes (armWrist_IkControl, plantIkHand,
and freeIkHand), and Shift+select the wristTransformCompensation null
node to add it to the selection last. Hit the p key to parent the
IK and locators to this null node.
Note - If the wrist and elbow seem to pop into a different
spot when you parent the armWrist_IkControl IK handle, you can correct
this. Simply select the armPoleVectorConstraint, highlight all its
translate channels in the Channel box, and then hit 0 and the Enter
key. This update problem occurs because of the nature of Maya's
lazy dependency graph evaluations.
-
Now select the armWrist_IkControl, plantIkHand, and freeIkHand nodes;
perform Modify, Freeze Transformations to zero out the IK handle and
locator's transforms; and put them in the same transformation space
as the wristTransformCompensation null node. You should remember that
this is also in the same orientation space as the wristJoint node.
This whole step is important because you will next orient-constrain
the wrist to the armWrist_IkControl IK handle node.
-
Select the armWrist_IkControl, Shift+select the wristJoint node,
and perform the menu command Constrain, Orient. So far, your nodes
should look like Figure 17.50 in the Hypergraph window.

Figure 17.50
Arm and wrist IK control hierarchy.
Now that you have all your controls in the proper transformation
space, you will finally create the constraints that enable you to
animate the hand freely and then plant it so that it sticks somewhere.
Again, you'll do this by using the weights of orient and point constraints.
-
Select the plantIkHand and freeIkHand nodes, and Shift+select the
armWrist_IkControl to add it to the selection last. Now perform the
two menu commands Constrain, Point and Constrain, Orient.
So far, if everything was done properly, you should have your wristJoint
orient constrained to your arm's IK handle. The IK handle, in turn,
is point- and orient-constrained to both plantIkHand and freeIkHand
locators, which both currently constrain it with a weighted average
of 1.
-
Next, select the armWrist_IkControl and use Modify, Add Attribute
to create a float attribute. Name that float attribute handPlant,
and give it a min of 0, max of 1, and default of 0. The settings should
look like those in Figure 17.51.

Figure 17.51
Adding attributes to the armWrist_IkControl.
Now that you have created the handPlant attribute on the armWrist_IkControl
IK handle, you want to make it control the weights of the constraints
between the plantIkHand and freeIkHand locators. This is achieved
using set-driven keys.
-
Go to the menu item Animate, Set-Driven Key, Set option box to bring
up the UI for creating set-driven keys.
-
Next, select the armWrist_IkControl IK handle and click the Load
Driver button. Be sure to highlight the handPlant attribute in the
upper-left section of the window.
-
Open the Hypergraph and select the two bottom constraints that are
children of the armWrist_IkControl node (the point and orient constraints
that you just finished creating in Step 16). These should be named
armWrist_IkControl_pointConstraint1 and armWrist_IkControl_orientConstraint1.
Hold the Shift key and add to the selection the plantIkHand and freeIkHand
nodes. Next, in the Set-Driven Key window, click Load Driven. Your
window should look like Figure 17.52.

Figure 17.52
Preparing to use the Set-Driven Key window.
The next few steps are very important for applying the set-driven
keys correctly.
-
First, be sure that the armWrist_IkControl IK handle's handPlant
attribute is set to 0 and is loaded as the driver node/attribute.
Also be sure that the node name armWrist_IkControl is highlighted
on the upper left and that the attribute name handPlant is highlighted
on the upper right of the Set-Driven Key window.
-
Now set the attributes on your nodes to the following values:
Driver attribute:
armWrist_IkControl.handPlant: 0
Driven attributes:
freeIkHand.visibility: on
plantIkHand.visibility: off
armWrist_IkControl_pointConstraint1.plantIkHandW0: 0
armWrist_IkControl_pointConstraint1.freeIkHandW1: 1
armWrist_IkControl_orientConstraint1.plantIkHandW0: 0
armWrist_IkControl_orientConstraint1.freeIkHandW1: 1
-
Now that your attributes are set exactly from the previous list,
with your driver node actively highlighted, go through the driven
nodes in the Set-Driven Key window and, one by one, click each node/attribute
in the Driven section. Highlight each name on the lower left, highlight
the attribute that you just set on the lower right, and hit the Key
button. For example, the first node to highlight on the bottom left
is the freeIkHand; on the bottom right, it is the attribute visibility.
With both highlighted, hit the Key button. Do this for each node's
attribute that you previously loaded and set, including each constraint
separately (see Figure 17.53).

Figure 17.53
Using the Set-Driven Key window.
Now that you have hit the Key button for each driven attribute value
when the driver is set to 0, you will set the values for the driven
attributes when the driver is set to 1.
-
Set the following node attribute's values:
Driver attribute:
armWrist_IkControl.handPlant: 1
Driven attributes:
freeIkHand.visibility: off
plantIkHand.visibility: on
armWrist_IkControl_pointConstraint1.plantIkHandW0: 1
armWrist_IkControl_pointConstraint1.freeIkHandW1: 0
armWrist_IkControl_orientConstraint1.plantIkHandW0: 1
armWrist_IkControl_orientConstraint1.freeIkHandW1: 0
-
Finally, repeat the previous step, but using the current values,
and set a driven key on each one of your driven node/attributes. One
by one, highlight them in the Driven section of the Set-Driven Key
window; one by one, highlight their attributes. Then hit the Key button
to set the driven node's attribute key at the current driver node's
attribute value.
Two locators control the location of the arm's IK handle as well as the
orientation of the wrist. For the most part, the freeIkHand locator can
be used to animate the hand when it does not need to be planted on something.
But now there's an extra node to use to plant and orient the hand on a
shot-by-shot basis, without ever needing to add extra controls to the
character. When you need the hand to transition from being free moving
to being planted somewhere, simply parent or point-constrain the plantIkHand
onto the object that the hand needs to be stuck to and then animate the
.handPlant attribute over a couple of frames, from 0 to 1. This hides
the freeIkHand locator, which you no longer need to animate, and makes
visible the plantIkHand locator, which you have stuck onto something.
In the next exercise, you will tackle the stretchy arm setup, which includes
creating all the controls, attributes, and node networks involved to make
an automatically stretchy IK arm that will stretch to maintain the distance
between the IK handle and the shoulder. Regardless of whether the location
of the shoulder or the location of the IK handle causes this distance
to become greater, the arm will still stretch automatically. You will
also add all the controls needed by an animator to animate this behavior
blended on and off, while still exposing manual controls to scale the
length on top of these controls.