Since I'm a MEL-junkie I'd like to take this tutorial a bit further. What if the scary scenario above was a request for a tiny change in a huge rig that would hold you at work for so long that you would definitely get in a fight with your girlfriend because you were late again...? Unwanted result! Don't you think it's possible to just copy the action from one driven key to another? Let's say you have made a rig for a index finger. Do you have to go through the same time consuming keying to get the same result on the other fingers? Certainly not. Because every action Maya does are visible for you in the scriptEditor you are able to modify some commands to avoid the fight with your girlfriend :) Let's go through an example...
I have created a simple hand-rig and renamed all the joints to appropriate names. e.g. the index finger is named like this:
index_tip (this one will never be animated because it is the outermost joint where the fingernail would be.)
I also added a simple template geometry for the two fingers I want to use as an example for this tutorial. If you want to try and follow the tutorial you can download the file I use as a starting point here or create your own hand. Maybe you already have one laying around:
To download final3_drivenKeysHandStartingPoint.ma
use this link.
The reason I want to rename the joints should be obvious. It's not impossible to work with joint1, joint2 etc, but it's more pleasant to work with logical names, especially when working with MEL. Usually you will find these options in a handRig:
- Curling all the fingers to shape a grip
- Curling joints separately
- Spread the fingers
- Thumb needs an additional control besides curl.
In this example I'm going to rig the index finger and then copy/ edit the commands I used to rig the middle finger too. OK, let's go!
Select the handControl. In the example above we used pCubeDriver.translateZ to control the pConeDriven.rotateZ. In this example we're going to create new attributes with custom names and values to control the fingers.
- To add your custom attributes, open the "Add Attribute" Window. Let's take a look at this window and go through the settings.
write desired name in this textfield. Note that if you write "/indexBase" Maya will display Index Base in the channelBox. However if you want to use the attribute in MEL you'll have to write "nHandControl.indexBase". If you can't remember what you called an attribute simply right-click it and choose Edit Attribute. The attributes for this control will be listed as they were originally typed in.
A vector is consisting of three floating point values.
An integer is a number with no decimals.
A string can be a collection of symbols from 1-9, A-z and special characters.
A Float is a number with desimals. E.g. 1.2577
A boolean is an on/off attribute.
0 = off and 1= on.
An Enum accepts selections from an "enumerated" or drop-down list. Useful for selecting different subdivisions on a model etc.
- Attribute Type. Don't worry about this one. We will use Scalar. Per Particle and Add Initial State are for particles.
- Numeric Attribute Properties: Here you can add items for your drop-down list and rename them.
OK. Now select nHandControl while you have the window open. Name the new attribute "curl", choose boolean and click "add". Notice the new attribute in the channelBox called "Curl". Change the value to "1" , right click the attribute and lock it. This attribute will only work as a separator. It doesn't look too good so you should experiment with other attributes. "_curl_" with a value of 0 and the data type integer for instance. An emum attribute with an enum name "section" looks good when locked. Note that if you wish to delete an attribute you have to unlock it first. I'll stick with this separator for this experiment.
Add a new attribute called "/index", Date Type "float" and give it a min value of "-10" and a max value of "10" . Set the default to "0". Click "add" . Now you should have two attributes in your channelBox
We don't really need visibility there because that will probably be controlled by another controller anyway's. Right-click it and choose "Hide Selected".
Add a new attribute called "middle" with the Data Type "Float" and hit "OK". Now we have what we need to go through the MEL example where I just edit the commands Maya prints in the scriptEditor to create a similar driven key setup at both fingers. I didn't bother about the min and max values because I can edit those with the "Edit Attribute" window later if I want to.
It's time to dig into the MEL part. Open the scriptEditor by clicking the icon all the way down to the right in the Maya User Interface or by choosing "Window > General Editors > Script Editor..."
By default Maya will not echo all the commands that are running in the background to keep the scriptEditor clean. However, now we really want it to echo all commands and therefore we choose "Script > Echo All Commands".
7 - Open the "Set Driven Key" Window and load "nHandControl" as Driver. Now select "jIndex_base", "jIndex_middle", "jIndexTop" and click "Load Driven". That's right. You can add multiple items when you're working with "Set Driven Key". It saves us some time because I want the attribute called "/index" to control all three joints and form a grip with the indexfinger.
It's from this point on we want to "record" what Maya does. Open the scriptEditor if you have closed it and go to "Edit > Clear History".We are going to set the neutral pose now where everything has a value of "0".
Select "nHandControl" and its attribute "Index", select
"jIndex_base" and its attribute "rotateZ" (Note: This applies to my rig. Your rig could be rigged differently and would possibly require another axis to be rotated) and hit "key". Select "jIndexMiddle", its attribute "rotateZ" and hit "key". Do the same with "jIndex_top".
Now we have keyed three joints in the neutral position and they are now bound to "nHandControl". While you did this, Maya pumped out valuable information for us.
setDrivenKeyframe -cd nHandControl.Index jIndex_base.rotateZ;
setDrivenKeyframe -cd nHandControl.Index jIndex_middle.rotateZ;
setDrivenKeyframe -cd nHandControl.Index jIndex_top.rotateZ;
We are not going to do anything with this now, but keep these lines in the back of your head. Continue setting up the finger. At "nHandControl.index" = -10 rotate the joints a bit backwards and set keys to all of them. WRITE DOWN THE VALUES YOU GET!!! in Notepad or somewhere because these values are important when we want to use MEL later.
A rule of thumb is to go all the way till it looks good and then a bit further so the animators can exaggerate it. These are my settings.