In the previous movie, we developed the basic premise on FK/IK joint matching
and created a basic MEL script to match the FK arm to the result arm.
In this movie, we'll continue to build on that framework to match the IK arm to the result arm.
Open the file "02-0- Character_Rigging_AppendixA_part2_start.mb"
and load the "0-FK_arms_snap.mel" script into the Script Editor,
or use your own files from the previous lesson.
Using the theory we developed in the previous movie,
we'll duplicate the IK controls as snap objects,
then parent them to the result arm and use the xform command
to move the IK controls to them when needed.
Start with the arm control. Duplicate it and rename the duplicate "leftArm_IK_snap_GRP".
Delete all its children and parent it to the leftHand_result_JNT.
In the Script Editor, copy and paste the FK hand snap portion of the script
and change the FK hand references to IK arm references,
and leftHand_FK_CTRL to leftArm_CTRL.
Because the IK control is concerned with both rotation and translation,
we'll have to duplicate this code again and match the translation as well.
Now pose the FK arm.
Back in the Script Editor, highlight only the portion of script pertaining to the IK match.
We don't want to accidentally run our FK match again.
Click the Execute button, rather than the Execute All button, and then switch back to IK mode.
The arm control matches, but how do we get the elbow to follow?
Presumably we could just create another snap group for the elbow and hook it up the same way.
However, that's not even necessary. Because the elbow is not concerned at all with orientation,
we can just snap its world space translation directly to the result forearm's translation.
Copy and paste the translation match script and change the upper arm reference to the forearm,
and the FK control reference to the leftArm_elbow_CTRL.
Set the arm back to FK mode and run the script again.
As you can see, the IK elbow now matches properly.
Great, now we can match the FK to IK arm as well as the IK to FK arm.
As usual, repeat for the right arm.
Although the script is functional, it has a number of problems.
First, looking at this scripting code could very easily become confusing.
This would be a lot easier to read if we could mark where each important section begins and ends.
We can use comments, messages denoted by double slashes
that are ignored during an Execute command, to do just that.
The second problem is that, it's kind of annoying having to manually change
to the opposite kinematic mode each time we run the script.
In general, we'll really only use this matching script when we intend to switch modes,
so why don't we just handle that automatically?
After the left arm FK matching portion of the script, add the line:
setAttr leftArm_settings_CTRL.FK_IK_blend 0;
Do the same for the right side.
Repeat this for the IK portion of the script, this time setting the respective blend values to "1".
Now if you run each portion of the script, Maya automatically switches the arm rig
to IK or FK mode after performing a match.
The last problem is that highlighting bits of script and clicking Execute
really isn't a convenient way to perform these tasks.
Instead, let's build a more visual user interface for our tool.
The UI will be comprised of a number of buttons that each activate a specific matching function.
Start by encapsulating the FK match and the IK match scripts in procedures named
"leftArm_FKtoResult()", "rightArm_FKtoResult()", "leftArm_IKtoResult()",
and "rightArm_IKtoResult()" respectively.
Remember to add these brackets ({ })so Maya knows where one ends and the other begins.
It's also a good idea to indent everything within each procedure.
Next, we'll begin our UI by creating a simple window called "matchApp" and showing it.
We'll also add a line before this that deletes any other previously opened matchApp windows.
Now that we have a window, we can create a couple of buttons in it.
Every window in Maya needs a layout before we can start placing widgets like buttons,
so let's use a basic column layout for now.
Create the first button with the "button" command and label it "Match Left FK Arm".
Use the --c (command) flag to instruct the button to run our "FKtoResult()" procedure.
Create a second button called "Match IK Arm" that runs the "IKtoResult()" procedure.
Now move the "showWindow" command to the bottom
to ensure our new widgets get displayed correctly.
Click the "Execute All" button.
Our matchApp appears with the two buttons. Try posing the arm in one mode
and clicking the appropriate button to match to the other mode.
To add the right side, we'll need to use a row column layout.
We'll use a flag to indicate two columns.
This will allow us to place the right and left buttons side by side.
Now insert the right arm buttons after their respective left arm buttons.
The buttons load side by side.
However, they aren't very clear. What is an animator going to think looking at the words
"Match FK Arm" and "Match IK Arm".
Are we matching to these arms, or from them? What are we matching them to?
You should always strive to make your UIs as clear as possible.
Go back to the Script Editor. Before the buttons, let's add some text.
We want the text to appear centered above the buttons,
so we can't just place it in the row column layout.
Instead, we'll encapsulate the entire control in a frame layout
that allows us to layer multiple different layouts on top of each other.
We'll label it "IK/FK Matching".
You can use the "text" command to add text.
We'll align it to the center and label it "Go to matching...".
We'll also add a horizontal "separator" to create some distance between our label and our buttons.
And finally, we'll change the button labels to read
"Left FK Arm", "Right FK Arm", "Left IK Arm" and "Right IK Arm".
Run the script again. Now there's little doubt what each button does.
Before we move on to the legs, there's another problem we're going to have to deal with.
Try stretching the IK or FK arms and then performing a match.
The arm doesn't line up properly.
In the next movie, we'll explore how to augment our scripts to take this into account.