
This kind of loop is very effective to use when you want
to change something for many objects. I'll go through
an example that shows this very well. I'll create a variable
where I store all the selected objects and then I'll
translate all of these objects in random directions.
string $ma_selectedObj[] = `ls -sl`;
for ($eachObj in $ma_selectedObj){
setAttr ($eachObj + ".translate") 0 1.2 0;
}
Say you create 5 polySpheres, select them and list them
in the string $ma_selectedObj[]. The command "ls"
lists things and the flag "-sl" is for selected.
So we list all the selected objects in that string by using
the
command. Also, we need the backquotes because we use a command
to cast the value into it.
This is what I get in the scriptEditor when I declare-
and print the variable:
string $ma_selectedObj[] = `ls -sl`;
// Result: pSphere1 pSphere2 pSphere3 pSphere4 pSphere5
//
print $ma_selectedObj;
pSphere1
pSphere2
pSphere3
pSphere4
pSphere5
So if we manually want to set the translate value to 0
1.2 0 we have to set this value 5 times like this:
setAttr ( $ma_selectedObj[0] + ".translate"
) 0 1.2 0;
setAttr ( $ma_selectedObj[1] + ".translate" )
0 1.2 0;
setAttr ( $ma_selectedObj[2] + ".translate" )
0 1.2 0;
setAttr ( $ma_selectedObj[3] + ".translate" )
0 1.2 0;
setAttr ( $ma_selectedObj[4] + ".translate" )
0 1.2 0;
If you have 5000 objects you can't do it like this... That's
why we create the loop. The for-in loop does this
by taking the first object in the list and executing the
command. Then it reads what the next item in the
selection is and does the same with that one. When there
are no more objects left in the list to pick from the
loop stops. The $eachObj variable here will substitute $ma_selectedObj[0],
then [1] and so on and so forth.
This loop sends me into another thing I'd like to talk
about. If I want a random value for all the translate-
values and I want to use them inside the loop, I have to
declare the random values INSIDE the loop. If
I declare it outside the loop the random value will not
be redeclared for all the objects. I'll write down the wrong
way and the correct way here so you can try them both.
//First off I cast the selection to a string
string $ma_selectedObj[] = `ls -sl`;
//I'll use a vector to set the random values:
vector $ma_translateVector = <<rand(0,2),rand(0,2),rand(0,2)>>;
//As you can see above the translateAttribute need three
floats to determine the values //for x, y and z. You can
also use translateX, translateY or translateZ to set the
//value for just one of them.
//Now, here's the loop:
for ($eachObj in $ma_selectedObj){
setAttr ($eachObj + ".translate") ($ma_translateVector.x)
($ma_translateVector.y) ($ma_translateVector.z);
}
The problem here is that within the loop we get the same
random values all the time because we declared it
once outside the loop. If we want a random value for each
element in the loop we have to make sure Maya
gets a chance to redeclare the variable every time the loop
is executed. To do this we need to put the
variable INSIDE the loop like this:
string $ma_selectedObj[] = `ls -sl`;
for ($eachObj in $ma_selectedObj){
vector $ma_translateVector = <<rand(0,2),rand(0,2),rand(0,2)>>;
setAttr ($eachObj + ".translate") ($ma_translateVector.x)
($ma_translateVector.y) ($ma_translateVector.z);
}
|