解压文件,将MXSPyCOM.exe放入到"C:\Program Files\MXSPyCOM\MXSPyCOM.exe",将initialize_COM_server.ms放入到"C:\Program Files\Autodesk\3ds Max 2024\scripts\Startup\initialize_COM_server.ms"
-- 数学表达式 + - * / ^ as(类型转换) -- 比较表达式 == != > < >= <= -- 逻辑表达式 or and not -- 判断 if ... then ... else ... if ... do ... -- case语句 语法一 for obj in geometry do ( local d = distance obj $cam1 case of ( (d <= 50): obj.segs = 40 (d <= 120): obj.segs = 25 (d <= 250): obj.segs = 10 default: obj.segs = 5 ) ) -- case语句 语法二 newObj = case cloneType.state of ( 1: instance pickedObj 2: reference pickedObj 3: copy pickedObj ) -- while 循环 while ... do ... -- for 循环 写法1,遍历数字: for i = 1 to 10doprint i 写法2,遍历数组: for item in [able] do x = x+item.height 写法3,在for循环里判断然后放到数组中: bigones = for obj in $Box* where obj.height > 100 collect obj
rollout test_buttons "Testing Buttons" ( button theButton iconName:@"PolyTools\TransformTools\PB_CW" iconSize:[20,20] button theBorderlessButton "I am a button, too!" border:false on theButton pressed do messagebox "Remember: Never press unknown buttons!" ) createDialog test_buttons 15060
checkbutton举例:
1 2 3 4 5 6 7 8 9
rollout test "Test" ( checkbutton setup "Setup" checked:true tooltip:"Opens setup panels" on setup changed state do if state == on then openRollout setup_pan else closeRollout setup_pan )
rollout pick_box_test "Pick Box Test" ( --filter all objects of class Box: fn box_filt obj = classof obj == Box --Pickbutton to select a Box from the scene pickbutton chooseit "Select Box" width:140filter:box_filt --If the user picked an object, then on chooseit picked obj do ( --see if the user did not cancel the picking... if obj != undefined do ( --if he did not, make the box's wireframe red: obj.wirecolor = red --and display the name of the object on the button: chooseit.text = obj.name ) )--end on )--end rollout createDialog pick_box_test
定义数组的语法是: #(数组内容)
用户可以将一个对象集和通配符路径名用 as 操作符转化为一个数组。这相当于给对象集或与路径名匹配的当前对象拍了一张“快照”,这样可以在随后的脚本里操作集合里的对象,而不用担心对象集改变。这种功能与 3ds max 用户界面下的 Named Selection Sets 按钮类似。如果用户删除了数组里的某一对象,而在随后的脚本里再对数组进行映射操作,系统会给出一个错误信息。
例子:
sel1 = Selection as array
Boxes_at_load = $Box* as array
snap_children = $torso…* as array
original_cameras = cameras as array
-- 通过对象或路径名得到其所具有的方法 b = box() showproperties b showproperties $Box001
集合和数组
数组的下标是从1开始的,不是0
集合是没有重复元素的,集合是无序的
定义数组: a = #(1,3,5,7,9)
定义集合: a = #{1,2,3,4,5}
修改数组的第三个数的值: a[3] = five
向数组追加内容: append a 11 输出的数值:1,3,5,7,9,11
通过表达式创建数组:
遍历1到5,然后对其进行开平方并存入roots的数组中.
roots = for i in 1 to 5 collect sqrt i
遍历的同时进行判断:
smallSpheres = for obj in geometry
where classOf obj == sphere and obj.numFaces < 50
collect obj
rollout SphereTool3 "Spheres Creator 3" ( local spheres = #() spinner count "Number: " type:#integer range:[1,100,10] spinner growth "Radius growth :" range:[1,100,10] button create "Create Spheres" button del "Delete Spheres" on create pressed do spheres = for i in 1 to count.value collect sphere radius:(i*growth.value) position:[i^2*growth.value,0,0] on del pressed do delete spheres
on growth changed val do for i in 1 to spheres.count do ( spheres[i].radius = i * val spheres[i].pos = [i ^ 2 * val, 0, 0] )
on count changed val do ( delete spheres create.pressed() ) ) create dialog SphereTool3 width: 300
getCurrentSelection() 返回一个数组,表示当前选择集。本函数相当于函数 Selection as array,但如果场景里有大量的对象,本函数的执行速度会大大快于后者。
基础对象集合的使用举例
举例1:
删除距离原点距离大于10000的几何体,使用 as array的作用是防止geometry发生改变而造成的影响
for o in geometry as array where (distance o.pos [0,0,0]) > 10000 do delete o
举例2:
举例3:
b2 = sphere radius:3 wireColor:red animate on for t in0 to 100 by 5 do at time t ( b2.pos = $ball.pos + random [-16,-16,-16][16,16,16] $ball.radius = 8+4*sin(720*t/100) )
fn railFollow obj line1 line2 u = ( -- u的值代表了从起始点到结束点的值,范围是从0到1,计算方式是(t-start) as float/(end-start) as float -- 计算位置,方向,距离 -- 通过lengthInterp可以得到在线的u的数值下的点位置 -- 通过nearestPathParam可以得到在线上,离p1点位置最近的点的位置的u值 -- 通过pathInterp可以得到在线上的u的数值下点的位置 -- p1-p2得到p1到p2向量 local p1 = lengthInterp line1 u, u2 = nearestPathParam line2 p1, p2 = pathInterp line2 u2, dv = p2 - p1, d = distance p1 p2 obj.pos = p1 obj.dir = dv obj.height = d )
start = animationRange.start end = animationRange.end animate on for t instarttoendby2do ( local u = (t - start) as float / (end - start) asfloat attime t railFollow $Box001 $Line001 $Line002 u )
控制器的使用
将box01的高度控制器赋予c
c = $box01.height.controller
创建一个路径约束控制器
pc = path_constraint follow:true bank:true path:$line01
创建一个路径约束控制器并赋予一个box的位置参数
$Box001.pos.controller = path_constraint follow:true bank:true path:$Line001
调整控制器的属性参数
$box01.pos.controller.bankAmount -= 0.25
复制控制器.
因为maxscript的变量赋值是引用赋值,所以第一句两个控制器变量是同一个值
使用copy语句以后会创建右边变量的一个副本来赋予左边
$box01.scale.controller = $box02.scale.controller
$sphere01.radius.controller = copy $box01.height.controller
得到控制器上的keys,返回一个数组
keys = $box02.height.controller.keys
得到keys后对应的可以使用的方法
keys = $box02.height.controller.keys
keys[1].value = 23
for k in keys do fomat “% at %\n” k.value k.time
button deleteChain "Delete Chain" width:100enable:false -- 负责生成锁链 fn updateChain = ( local len = curvelength curve, -- 曲线的长度 uStep = (diam.value - thickness.value) / len, -- 环的直径减去厚度等于内圈的直径,再除以曲线的长度可以得到一个圆环占曲线长度的比例 up = true, i = 1 for u = 0.0to1.0by uStep do ( if i > chain.count then chain[i] = torus wireColor:wireColor.color local t = chain[i] t.radius1 = diam.value / 2 t.radius2 = thickness.value / 2 t.pos = lengthInterp curve u t.dir = lengthTangent curve u -- 方向一次x,一次y coordsys local rotate t 90 (if up then y_axis else x_axis) up = not up i += 1 ) for j in i to chain.count do ( delete chain[i] deleteItem chain i ) )
on pickCurve picked obj do ( curve = obj theCurve.text = obj.name deleteChain.enabled = true updateChain() )
on deleteChain pressed do (delete chain; chain = #()) on diam changed val do updateChain() on thickness changed val do updateChain() on wireColor changed val do chain.wireColor = val )
for f = animationRange.startto animationRange.enddo ( sliderTime = f for i in1to obj.numVerts do ( local v = coordsys origin getVert obj i local dv = if vertStore[i] == undefined then v else v - vertStore[i] vertStore[i] = v format"%, %, %\n" (f.frame asinteger) (i-1) dv to:file ) ) closefile edit fileName ) exportMesh $Sphere001 "E:/3dsmaxTest/test.txt" $Sphere001