|
Page 2 of 2
Tip #6: Be specific
Bit of an obvious one here, but it does happen. When you're starting out with MEL scripting, it's very tempting to just copy and paste the contents of the script editor without really "generalising it", or making it safe for reuse. For example, let's imagine we're making a script to create a cube and stick some simple animation on it. This is (more or less) what Maya prints out in the script editor if you create a cube and set a key, then move and key it again:
polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
currentTime 1;
setKeyframe -breakdown 0 pCube1.translate;
move -r -os -wd 0 0 5;
currentTime 10 ;
setKeyframe -breakdown 0 pCube1.translate;
This is fine as a starting point, but if you start using code like this in your scripts a lot then it'll break pretty quickly. Imagine, for example, if the user runs this script twice. The first time round, it'll all work perfectly. But the second time, the object "pCube1" already exists, and the cube that Maya creates on line 1 of the script will be called "pCube2" instead. Lines 3 and 6 will operate on pCube1, and line 4 will operate on whatever object happens to be selected at the time (probably pCube2). So that's obviously not particularly good! Let's try reworking it to make it a bit more generic:
string $cube[] = `polyCube`;
setKeyframe -time 0 -value 0 ($cube[0] + ".translateX");
setKeyframe -time 10 -value 5 ($cube[0] + ".translateX");
Much better! We now store our cube's name in a variable as soon as it's created, and then use this variable further on in the script to tell Maya exactly what we want keyframed, and how. This is much less likely to break, and is how a large proportion of Maya's built-in scripts work. I also took the opportunity to remove the 'move' and 'currentTime' commands; it's much better for us to tell Maya exactly where, when, and how we want our commands to run with flags, instead of changing our current selection/time, and then hoping that Maya will always do the right thing when we call "setKeyframe".
Finally, you should also be aware that changing selection is also not particularly fast; if you ever find yourself writing a script that makes lots of calls to the "select" command or doesn't specify an object name after a command, then in 90% of cases you're doing it wrong. The more specific we are with Maya, the smaller the chance that it'll misunderstand us, and the smaller the chance that your script will eventually break!
Tip #7: objExists works on attributes too
I don't know about you, but I safety-check as much as I can. I make it my personal mission that if my code must error, it'll always be a nice friendly user-readable error that I've coded, and never a MEL syntax error or something equally silly. It's more code, but it's quick to write. So quite a lot of this checking involves making sure attributes exist (before getting its value for example), and I used to do this with "attributeExists". But the problem is, I can never remember how it works or what order its arguments are. Is it object then attribute, or attribute then object? Then a genius at work (Hi Diego!) told me that objExists works on attributes too:
if(`objExists ($cube + ".translateX")`)
$value = `getAttr ($cube + ".translateX")`;
Much easier to remember, eh?
Tip #8: ls can be used to search for custom attributes
Following on from tip #7, "ls" also works with attributes. So, if you added a custom attribute to the root node of all your character rigs (called "keCharacterRig" for example), then you could then search for all rigs in the scene like this:
string $allRigs = `ls "*.keCharacterRig"`;
Which is pretty awesome - it gives you a great way to "tag" certain objects and quickly look for them later. Imagine working on a crowd scene, or a scene with a large number of props. Suddenly, writing a script to find and update all character rigs in the scene becomes a piece of cake Jason Schleifer mentions on one of his DVDs that Weta used a technique like this in their pipeline to manage their assets in their Maya scenes for Lord Of The Rings.
Tip #9: Looping over arrays
Many people do this (me included):
int $i;
int $size = size($array);
for($i = 0; $i != $size; ++$i)
print("Looping on " + $array[$i] + "\n");
Which is ok, I suppose. But if you only need read-only access to the array then this other way is easier to read, and shorter too. It's a matter of taste as much as anything, but at least you know it exists now... 
string $item;
for($item in $array)
print("Looping on " + $item + "\n");
Tip #10: Overwriting functions
So what happens if you source a procedure with the same name as another procedure that Maya already knows about? Well, Maya starts using the new one instead of the old one. This is what you do every time you run a script in the script editor; hopefully this shouldn't be anything new to you. Now, this immediately makes for a great debugging tool. I was once debugging a problem with an animator's scene where an expression would automatically run whenever they opened their scene, and the script it was calling was trashing their scenes before they could stop it (we'll call this script global proc KE_TrashMyScene(int $value), for the sake of argument). What did I do?
global proc KE_TrashMyScene(int $value)
{
}
Yep - I neutered the problematic function so that it still existed but no longer did anything. I could then reopen the scene without any nastiness occurring, and from there disable the troublesome expression permenantly. Note that this solution wouldn't have been possible if the expression had used "source" - another good reason to ditch it! (see my earlier point about the evils of "source").
So yes, this is a slick debugging tool that lets you 'turn off' any function you think might be causing problems. But there's more to it than this - a large part of Maya's functionality is MEL scripts and functions; you know this from watching Maya execute stuff in the script editor as you click around the interface. If you look in your Maya install directory's "script" folder, it's all there for viewing.
So if you use function overwriting on Maya's built-in functions, what do you think happens? That's right - you can completely change the way that Maya works, just by looking to see what some of its procedures are called and sourcing files that replace those procedures with your own versions. This, to me, is nothing short of amazing. This is also exactly how my works - it just overwrites the MEL procedure Maya uses to open a file browser with a different one that opens a kdialog or zenity instead.
But you don't have to stop at file browsing, oh no. Sick of Maya always using Windows Media Player or fCheck to open your playblasts on Windows? Download a nicer video player, and make Maya use that for playblasts instead! Do you wish Maya checked saving was successful and made a popup if it failed, instead of a well-hidden error message in the script editor? Easy! Whilst Maya's user interface can be pretty awkward to use at times, it really makes up for it with an amazing amount of power for modifying it to suit your tastes.
I really hope this was helpful for you. Thoughts? Comments? Things you disagree with or feel strongly about? Please let me know!
<< Start < Prev 1 2 Next > End >> |