Howto: Maya scripted animation with MEL
This is basicly the same code I used for the old video I posted. Since then I’ve received a couple of requests on how to get that code to work. So I’ve finally fixed it up a bit and made it a bit more user friendly.
Download the Maya 2008 SP1 project files: Melanim.rar
Download the code in txt format: infectiousmelcode.txt
int $startnum = 1;
int $endnum = 125;
int $startobject = 1;
float $distace = 1.5;
float $slow = 0.3;
string $name = "pCube";
//init
//on frame 2 we run through all the objects(except for object number 1) and give them a random rotation and scale them to zero
if (frame == 2) {
int $z;
for ($z = $startnum; $z <=$endnum; $z++) {
if ($z != $startobject) {
float $rand = rand(1) * 360 ;
setAttr ($name + $z + ".rotateX") $rand;
setAttr ($name + $z + ".rotateY") $rand;
setAttr ($name + $z + ".rotateZ") $rand;
setAttr ($name + $z + ".scaleX") 0;
setAttr ($name + $z + ".scaleY") 0;
setAttr ($name + $z + ".scaleZ") 0;
}
}
}
if (frame > 2) {
for ($x = $startnum; $x <= $endnum; $x++)
{
float $attrx = getAttr ($name + $x + ".scaleX");
float $attry = getAttr ($name + $x + ".scaleY");
float $attrz = getAttr ($name + $x + ".scaleZ");
float $attrrx = getAttr ($name + $x + ".rotateX");
float $attrry = getAttr ($name + $x + ".rotateY");
float $attrrz = getAttr ($name + $x + ".rotateZ");
float $attr[3] = `xform -ws -q -piv ($name + $x)`;
if (($attrx != 1) || ($attry != 1) || ($attrz != 1) || ($attrrx !=0) || ($attrry !=0) || ($attrrz !=0))
{
// now go through all other objects and check
// if nearest objects are visible
int $y;
for ($y = $startnum; $y <=$endnum; $y++) {
if ($y != $x) {
float $attr2x = getAttr ($name + $y + ".rotateX");
float $attr2sz = getAttr ($name + $y + ".scaleZ");
if ($attr2sz > 0.8) {
float $attr2[3] = `xform -ws -q -piv ($name + $y)`;
float $distancex = $attr[0] - $attr2[0];
float $distancey = $attr[1] - $attr2[1];
float $distancez = $attr[2] - $attr2[2];
float $dist = sqrt ($distancex*$distancex + $distancey*$distancey + $distancez*$distancez);
float $randnum = rand(1);
if (($dist <= $distace) && ($randnum > $slow)) {
float $attribtemp = getAttr ($name + $x + ".scaleX");
if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
if ($attribtemp > 1) $attribtemp = 1;
setAttr ($name + $x + ".scaleX") $attribtemp;
$attribtemp = getAttr ($name + $x + ".scaleY");
if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
if ($attribtemp > 1) $attribtemp = 1;
setAttr ($name + $x + ".scaleY") $attribtemp;
$attribtemp = getAttr ($name + $x + ".scaleZ");
if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
if ($attribtemp > 1) $attribtemp = 1;
setAttr ($name + $x + ".scaleZ") $attribtemp;
$attribtemp = getAttr ($name + $x + ".rotateX");
if ($attribtemp != 0) {
$attribtemp = $attribtemp * 0.75;
if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
setAttr ($name + $x + ".rotateX") $attribtemp;
}
$attribtemp = getAttr ($name + $x + ".rotateY");
if ($attribtemp != 0) {
$attribtemp = $attribtemp * 0.75;
if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
setAttr ($name + $x + ".rotateY") $attribtemp;
}
$attribtemp = getAttr ($name + $x + ".rotateZ");
if ($attribtemp != 0) {
$attribtemp = $attribtemp * 0.75;
if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
setAttr ($name + $x + ".rotateZ") $attribtemp;
}
}
}
}
}
}
}
}
How to use this?
Create a new scene, create a bunch of objects (I just created a cube and duplicated) where you want them to be at the end of the animation. Make sure their object names are all the same followed by a number. Also make sure that their scales are on 1 and rotations on 0.
Now open up Window->Animation Editors->Expression Editor.
Go to Select->By Expression Name, type a name for the script under Expression Name, paste the code in the code window.
You’ll need to alter the values at the top of the script to work for your scene.
$startnum should usually be 1, but if your objects start at a different number, replace the 1 in the code.
$endnum is the number of the last object.
$startobject is the number of the object where the animation will start from.
$distance is the maximum distance between objects before the animation will start kicking in.
$slow is to slow the animation speed down, the higher the value the slower it will be (has to be between 0 and 1).
$name is the prefix for your object names, in the example scene you’ll see I use pCube1 to pCube125.
Click Create. Hopefully maya wont complain about anything. You can close the window now and click play.
To actually render the animation you’ll have to bake it by using Edit->Keys->Bake Simulation. And then delete the mel script from the Expression Editor, the baked animation should now play realtime and be renderable.
Good luck and don’t be afraid to play around with the code. Feel free to post comments below if you have questions or anything.
