其他相关操作讲解:
.count : integer --数组元素的个数,只能读取。integer表明执行此命令返回整数。如a.count返回5,说明这个数组一共有5个元素。
[] = --修改某元素的值。如a[1] = 100,再看一下数组a变成了#(100, 2, "cg", 11, 123.0)即第一个值发生了改变。
as array --把集合转变成数组。如:b = lights as array即把场景所有灯光存储为数组并赋值给b。
append --向数组里面增加元素,如:append a "zyz"即向数组a里面增加元素"zyz",得到新数组,增加的新元素排在数组最后面,这样数组a变成了:#(100, 2, "cg", 11, 123.0, "zyz"),a.count也返回了6。
deleteItem --删除数组某个元素。如:deleteitem a 4即把数组a的第4个元素删除,数组序号自动往前移动一位,这时我们得到:
#(100, 2, "cg", 123.0, "zyz")
findItem --寻找数组里面是否有某元素。如:finditem a "cg",如果找到了某元素,返回第一次找到此元素的序号(因为数组里面的元素是可重复的),如果找不到,则返回0。
数组还有其他一些操作语句,以后再详细讲解。
循环语句
for loop
for循环可以逐个计算一列数值,集合,数组等,
语法:for(in | = )( do | collect)
是循环中的第一个单独的变量,是循环的源数值,是表达式,|号左右表示可选项。下面来看看实例:
例一:for i in 1 to 10 do print i --输出1到10
print 输出函数,后面接所有类型数值,如print selection[1].name --输出选择的第一个物体的名字
刚才那句执行的顺序是:首先赋值i =1,然后执行print i 就输出 1,再 i 进行自加,变成了2,又执行print i 输出2...一直到 i=10输出10才算完。这样就进行了循环。而且是第隔1个数值输出一个值。
例二:for i in 1 to 10 by 2 do print i --每隔两个数来输出i,于是我们就得到了奇数1,3,5,7,9。by就是控制每隔多少数值再执行do后面的表达式。默认不用by,则都是每隔1个数值执行一下。
例三:for i in selection do i.name += "new"
selection即所有选择的物体,相当于美元符号"$",但是用法有时候不同。
selection.count即选择物体数量,selection即选择中的第 i 个物体,selection类似一起来个数组。上面那句的意思是,把所有选择物体的名字后面加一个"new",你再看看你选择的物体名称。上面代码还可以写成:
for i in $ do i.name += "new"在程序中建议尽量使用selection,因为如果你没有选择物体,那么这句就会出错。
这两句是直接访问数组元素,从第一个开始,而不像前面的for i in 1 to 10...还要数元素序号。这一句就跟平常简单的英文会话一样,可以翻译成:如果i(变量)在selection(选择物体)里面,那么就do(做)什么。
例四:for i in lights do i.on = false这句意思是说,把场景所有灯光关掉,i.on是开,i.off是关,跟日常开关一样。有人也许会问,你怎么知道所有灯光用lights表示呢?max工具栏上有个过滤器,想必大家都用过,里面有all,geometry,shapes,lights,cameras,helpers等,比如你想改所有for i in cameras do...就是对所有摄像机操作了。
但all在脚本里并不是所有物体的意思。
再回来看例四,你打个有目标点的灯光试试,再用那句就会出错了,因为lights把灯光目标点也算在内了,而目标点是没有开关的,那怎么办呢?这就要把它过滤掉。
for i in lights where classof i != targetobject do i.on = false这里面加了一句where classof i != targetobject 这句相当于一个过滤器,当变量i 在light里面逐个执行的时候,先要过这一关,如果classof i != targetobject返回true就继续执行do后面的语句,如果返回false就直接跳到下一个元素。这里用到了maxscript的比较运算符!=,maxscript比较运算符即把两个数据进行比较,返回true 或者false。
假设a 和 b是分别要比较的两个数据,下面即把a ,b进行比较:
a == b --相等,如果相等就返回true,不相等就返回false,下面道理相同
a != b --不等于
a > b --a大于b
a < b --a小于b
a >= b --a大于等于b
a <= b --a小于等于b
例如: 1 > 2返回false,1 >= 1返回true
这里还用到了类别运算classof,classof是用来判断一个max节点的类别的,用法是直接classof + 节点,如果我们不知道一个物体的类别,就直接选择它然后classof $,即判断选择物体的类别,比如上面我本来不知道灯光目标点的类别,于是我选择一个目标点,再运行classof $,就返回了它的类别targetobject,这样,就可以过滤掉所有类别是targetobject的物体,以免出错。
下面讲重命名脚本,我们看到一些脚本里都有重命名功能,其实这个功能写出来非常简单。
上面的例三就是一个重命名功能,for i in selection do i.name += "new",是在所有选择物体后面加个“new"。真正的重命名脚本如下:
例五:for i in objects do i.name = uniquename "cg"
这里用到uniquename,它的原理跟你创建物体的命名一样,把物体以所给字符串为基础进行命名,后面跟数字序号。
比如我执行上面那两句之后,再看场景中的物体名字分别变成了cg001,cg002,cg003...objects --即场景所有物体,objects.count即场景所有物体数量。
objects即场景中的第 i 个物体。objects也类似一个数组。
再把上面那句改一下:
例六:newname = "zyz"
for i in objects do i.name = newname + "_" + i.name
这里就是将所有物体objects的名称加个前缀"zyz_",这个下划线"_"并没有先赋值,这里是想说,newname + "_" + i.name这一句可以是任意的字符串,可以用加号进行调整。上面是先把名称"zyz"赋给变量newname,然后再调用它,建议大家以后也这样先赋值再调用,这样程序修改起来就方便了。
下面进行扩展:
例七:for i in cameras do i.name = uniquename "mycamera" --把场景摄像机名字改成mycamera001,mycamera002,mycamera003...
例八:for b in $box* do b.name = uniquename "mybox" --把场景所有名称以"box"开头的物体重命名,$box就是名称为box的物体,后面加一个通配符"*"就表示任意字符,$box*就是指名称以"box"开头的物体。注意变量b前后要一致,小心都写成了i。
例九:for v1 in lights where classof v1 == vraylight do v1.subdivs = 12 --把场景中所有vraylight的细分调到12
例十:for g in geometry do g.wirecolor = red --把所有几何体的线框色改成红色,颜色常量请查看第二节。