从事了几年游戏美工,自学了一些MAX的脚本语言,现来分享一些简单实用的功能
MaxScript 语法有些类似C++ 但是比C++要更高级的MaxScript教程,更方便。
首先是如何打开脚本窗口
MaxScript有两种脚本编辑窗口
左边的叫做Linstener窗口,用于运行单行程序以及给出反馈,一般用来测试代码。
右边的就是编辑窗口,可以运行一整套代码。
由于这里基本都不是学编程的,所以我也不会像教编程一样,按套路来。
还是总结一些新手比较多见的问题。
1.如何去除已经赋予物体的材质球。
赋予物体材质球,大家基本都会,不会的再去自学一下。。。。
但是如何去除材质球,相信许多人都一直想知道。。。。
通过选中物体,然后输入代码
$.material = undefined
可以轻松实现
接下来 来解释下这条代码。
》》》》》 符号: $ 《《《《《
名称:dollar sign
中文:美金符号
输入方法:在英文输入法下 shift+4
作用:返回当前选中物体的基本属性
如图红色区域为代码输入区域,白色为返回值区域
选中物体为一个立方体BOX 简单输入$
返回$Box为选中物体的类别,由于没有塌陷成多边形,所以物体类别是Box
Box442为物体的名称
之后[-794.023926,-1784.491333,0.000000]为物体的世界坐标,注意,这里单位显示为英寸,是MAX的标准单位。换算成其他单位的话 需要自行转化。
$.material 中 句号(.)的意义为 当前选中物体的某一项属性,material就是材质
$.material = undefined中 undefined 的意义为 “未定义”
等号(=) 顾名思义,就是设置参数
把选中物体的材质属性设置为未定义
就达到去除材质球的作用。
2.数学运算和逻辑运算
max的Listener窗口,还能进行一些数学运算。
比如 整数运算 50 + 50 对应输入100
sin 90度 结果为 1
反三角函数 asin 0.5的结果 则为30度
50的倒数为0.02
圆周率在max中 为 3.14159
接下来的3个 5/2是脚本中比较容易弄错的。
在计算机语言中 分 整数和浮点数两种不同的数字类型。
5除以2 被计算机认为整数运算 所以 5/2在日常生活中,答案为2.5,但是由于计算机默认成整数运算,所以会把小数部分忽略,所以返回的结果 就是2 (没有4舍5入)
下来的5.和5.0其实是一样的,计算机语言中 整数后跟小数点,就会被认为是浮点数,不需要再写成5.0。
之后 浮点数 与 整数进行运算,输出结果也为浮点数。 所以5.0/2结果为2.5
BTW:0和1之间的数字 也可以输入为 .x(x为数字) 而不用输入成 0.x
接下来 x = 1
很容易理解,就是 定义一个变量 x,x的值为1
所以返回结果为1
接下来x == 2
两个等号 为比较运算符(逻辑运算符的一种),可以理解为 x的值和2对比 如果相同,则返回true,如果不同,则返回false
可以看到 x == 2返回的是false 而 x == 1返回的true
还有其他的比较运算符 比如 >(大于) , <(小于) , >=(大于或等于) , <=(小于或等于) , !=(不等于 注意 感叹号 记作 非 运算符 也就是 not)
3.设置随机物体线框颜色
场景中,如果有一堆物体,但是为了容易分别,想设置成不同的颜色,
手动设置,肯定是噩梦。
接下来,神奇的脚本就可以轻松实现
首先,选中需要改变颜色的物体
有多种实现方法,我提供了2种:
$.count 会返回选中物体的数量
运用 for 循环
举个例子
这是 for 循环的一个概念。 i 是一个变量,可以记成任何名称,比如 你可以改成 index 改成 object 改成 a 改成 b 都可以。。1 to 10代表 从1开始到10的数字(包括 1和10),
第一条中 我从1 循环到 物体的数量 每循环一次 就会 定义三个随机数 代表 r g b 红 绿 蓝 3个颜色 分别从 0 到 255(涉及到计算机图形知识,不详细解释)
random是一个max自带函数 需要2个数字作为参数 分别是上限和下限,用空格隔开 所以 记作 random 0 255 就是随机从0到255(包括)中的任意数字
接下来 selection[i]
selection为当前选择集,其作用和$类似,具体区别,不太清楚(selection返回的是一个集合,都记作$selection 。$在选中单个物体时,会返回这个物体的属性)。。写作$[i]也可以运作。
后面的[i]表示选择集中 第 i 个物体 所以 selection[1]就表示为 该选择集中,排名第一个的物体。 之后 括号内的操作 都是针对这个物体,当全部执行完后,i会增加1 一直循环到 最后一个物体。
之后 wirecolor 为 物体的线框颜色(注意,如果有材质球,线框颜色不会影响到物体表面颜色。)
之后 (color r g b)
color 也是一个max自带函数 需要 红 绿 蓝 三种数值,分辨为 0到255的数字
第二种方法更为简单粗暴
直接将 i(stand for "index" index的首字母,其实 这里 i 改成 o(object)命名更合理 who care...) 定义为选择的物体
由于 i 本身就是一个物体变量, 所以 不需要再通过索引的数字来循环物体。
所以 i.wirecolor 直接就是 当前物体的线框颜色
4.检查物体缩放
在制作模型的时候,难免会用到缩放功能,导致物体的缩放量不是1,之后再导入导出模型到其他地方的时候,产生比例变化。 十分头疼
接下来 给大家一个检查缩放量的方法。
这次,我选择 在 geometry中进行挑选 geometry是几何体的英语,这样的操作,目的在于不会选中场景中的虚拟体,灯光,摄像机等非几何体。
where则是类似一个筛选的命令 在几何题中 只选择 transform中scale(transform有三项,分别为位移,旋转和缩放)。我只选择缩放属性有改变(不为[1,1,1]分别对应 x y z轴)
由于我不需要对那些物体进行操作,只需要筛选出来,所以这里用到collect i 而不是之前的 do
把选中的物体 加入到一个选择集中 我把这个集命名为c(collection)
这样
使用 select(选择)命令 选中选择集c 就可以把所有 带有缩放信息的物体挑选出来,单独进行x-form也行
配合 for i in $ do i.scale = [1,1,1],把尺寸调回到原先也可以。
5.重新实例关联物体。
在建模场景时,可能会有大量的重复复杂物体,会用到大量实例复制。
有时候,都是先做完一个物体,再去复制出其他的。 但是这样会造成比例不好把握。
现在提供一种反向思路,不如先把物体摆在那里,控制好比例,再去单独调整一个物体。
最后 通过脚本 把没有修改过的模型与完成的模型进行关联。
OK, Let's go
我不打算在这里教如何制作UI, 所以 这里 提供纯代码教学,如果对Maxscript有兴趣的话,可以自行搜索如何制作UI。
首先,定义为一个变量,让变量的值成为修改过的模型
选中修改过的模型
假设变量名为 x(源模型)
x= $
选中需要修改的模型
$.baseobject = x
在编辑窗口中,写完代码,
使用Ctrl+E进行全部执行
Shift+Enter为执行当前选中行。。
这样,所有的模型都自动关联成源模型(还是实例关联,修改任何一个 其他都能相应修改)
大家要问了,那和重新复制 有什么区别呢?
接下来介绍下这个方法的特性
像这样一个圆形阵列,或者一些 不规则的角度甚至有大小缩放,重新复制 会比较麻烦。
运用上面的脚本,可以之前就定义好大小和角度。最后再关联形状。
短短两行代码,省去了大量的操作,是不是很方便呢。
大家有什么觉得特别重复劳动的问题,可以跟帖提问。。这些功能性的脚本,可以发掘。
提供一个之前写的脚本。。。没什么特别的,都是功能性插件。
需要基于算法的就不发出来了。BUG比较多。。
使用方法,
把所有代码复制到一个txt文件中,然后把txt后缀改成ms
直接拖到max中 就可以使用,其中批量导入导出可能会因为版本问题有bug 我是基于2010编写的脚本,所以。。。
有兴趣的欢迎讨论~~
if myTools !=undefined do destroydialog mytools
base = undefined
file_path = maxfilepath
export_op = exporterPlugin.classes
t_obj = export_op[14]
t_3ds = export_op[1]
t_ascii = export_op[16]
t_fbx = export_op[8]
selectionarray = #()
Fn getnames Title FilterName =
(
dialog = DotNetObject "System.Windows.Forms.OpenFileDialog"
dialog.title = Title
dialog.filter = FilterName
dialog.Multiselect = true
OpenFileResult = dialog.ShowDialog()
if OpenFileResult.Equals OpenFileResult.OK then
(
dialog.FileNames
)
else Undefined
)
rollout myTools "My Tools" width:225 height:341
(
rollout imp_open "批量打开/导入" width:172 height:123
(
button open_max "MAX" pos:[11,90] width:148 height:24
button imp_obj "OBJ" pos:[90,14] width:69 height:29
button imp_3ds "3DS" pos:[11,51] width:69 height:29
button imp_ase "ASE" pos:[90,51] width:69 height:29
button imp_fbx "FBX" pos:[11,14] width:69 height:29
on open_max pressed do
(
file_names = getnames "选择打开文件" "MAX (*.max)|*.max"
if file_names != undefined do
(
for f in file_names do mergemaxfile f
destroydialog imp_open
)
)
on imp_obj pressed do
(
file_names = getnames "选择导入文件" "OBJ (*.obj)|*.obj"
if file_names != undefined do
(
for f in file_names do importfile f #noprompt
destroydialog imp_open
)
)
on imp_3ds pressed do
(
file_names = getnames "选择导入文件" "3DS (*.3ds)|*.3ds"
if file_names != undefined do
(
for f in file_names do importfile f #noprompt
destroydialog imp_open
)
)
on imp_ase pressed do
(
file_names = getnames "选择导入文件" "ASE (*.ase)|*.ase"
if file_names != undefined do
(
for f in file_names do importfile f #noprompt
destroydialog imp_open
)
)
on imp_fbx pressed do
(
file_names = getnames "选择导入文件" "FBX (*.fbx)|*.fbx"
if file_names != undefined do
(
for f in file_names do importfile f #noprompt
destroydialog imp_open
)
rollout file_op "批量操作" width:175 height:128
(
button save_obj "批量MAX" pos:[91,47] width:70 height:67
button op_obj "批量OBJ" pos:[91,12] width:70 height:32
button op_3ds "批量3DS" pos:[11,47] width:70 height:32
button op_ascii "批量ASCII" pos:[11,82] width:70 height:32
button op_fbx "批量FBX" pos:[11,12] width:70 height:32
on save_obj pressed do
(
if selection.count>0 then
(
for i in selection do savenodes i (file_path + "\\\\" + i.name + "single" + ".max")
messagebox("保存完毕,路径为 " + file_path)
destroydialog file_op
)
else messagebox"请选择物体以保存"
)
on op_obj pressed do
(
for i in 1 to selectionarray.count do
(
select selectionarray[i]
exportfile (file_path + "\\\\" + selectionarray[i].name +".OBJ") #noprompt selectedonly:true using:t_obj
)
messagebox("导出完毕,路径为 " + file_path)
destroydialog file_op
shelllaunch "explorer.exe" file_path
)
on op_3ds pressed do
(
for i in 1 to selectionarray.count do
(
select selectionarray[i]
exportfile (file_path + "\\\\" + selectionarray[i].name +".3DS") #noprompt selectedonly:true using:t_3ds
)
messagebox("导出完毕,路径为 " + file_path)
destroydialog file_op
shelllaunch "explorer.exe" file_path
)
on op_ascii pressed do
(
for i in 1 to selectionarray.count do
(
select selectionarray[i]
exportfile (file_path + "\\\\" + selectionarray[i].name +".ASE") #noprompt selectedonly:true using:t_ascii
)
messagebox("导出完毕,路径为 " + file_path)
destroydialog file_op
shelllaunch "explorer.exe" file_path
)
on op_fbx pressed do
(
for i in 1 to selectionarray.count do
(
select selectionarray[i]
exportfile (file_path + "\\\\" + selectionarray[i].name +".FBX") #noprompt selectedonly:true using:t_fbx
)
messagebox("导出完毕,路径为 " + file_path)
destroydialog file_op
shelllaunch "explorer.exe" file_path
)
)
rollout instance_check "Instance" width:203 height:201
(
pickbutton btn26 "拾取" pos:[63,41] width:82 height:28
GroupBox grp1 "拾取实例源对象" pos:[14,10] width:182 height:118
button btn34 "实例化目标" pos:[35,146] width:129 height:29
label lbl3 "源对象:" pos:[29,92] width:48 height:18
label lbl4 " " pos:[81,90] width:103 height:25
on btn26 picked pickobj do
(
base = pickobj
lbl4.caption = base.name
)
on btn34 pressed do
(
if selection.count > 0 and base != undefined then
(
$.baseobject = base.baseobject
$.material = base.material
)
else messagebox"请选择需要被实例化的对象"
)
)
button check_transform "检查变换" pos:[14,11] width:94 height:31
button invselection "反向隐藏" pos:[14,53] width:94 height:31
button btn10 "Rename" pos:[14,95] width:94 height:31
button btn21 "Re_Instance" pos:[14,137] width:94 height:30
button modifiers_on "开" pos:[24,190] width:34 height:20
button delmod "删除修改器" pos:[14,218] width:94 height:31
button saveobj "批量存储" pos:[14,257] width:94 height:31
button import_but "批量导入" pos:[14,296] width:94 height:31
button set_pivot "对齐轴心" pos:[118,11] width:94 height:31
button WP_edit "Edit" pos:[123,64] width:41 height:20
GroupBox workpivot_gup "工作轴" pos:[116,44] width:100 height:46
button WP_use "Use" pos:[169,64] width:41 height:20
button modifiers_off "关" pos:[64,190] width:34 height:20
groupBox grp3 "修改器开关" pos:[16,172] width:91 height:41
on myTools close do
(
destroydialog instance_check
destroydialog file_op
destroydialog imp_open
)
on check_transform pressed do
(
istrans = for o in objects where o.scale !=[1,1,1] collect o
if istrans.count>0 then
(
select istrans
unhide selection
)
else messagebox"检查完毕."
)
on invselection pressed do
(
if selection.count>0 then
(
unhide objects
hide selection
clearselection()
)
else messagebox"No selection"
)
on btn10 pressed do
(
for i in objects do i.name = " "
for i in objects where (classof i == Editable_Poly or classof i == Editable_mesh) do i.name = uniquename "Polygon"
for i in objects where (i.modifiers.count == 0 and classof i == box) do i.name = uniquename "Box"
for i in objects where (i.modifiers.count == 0 and classof i == Sphere) do i.name = uniquename "Sphere"
messagebox"rename done"
)
on btn21 pressed do
(
createdialog instance_check
)
on modifiers_on pressed do
for i in selection where i.modifiers.count > 0 do for m in
i.modifiers.count to 1 by -1 do i.modifiers[m].enabledInViews = true
on delmod pressed do
(
if selection.count > 0 then
for i in selection where i.modifiers.count > 0 do for o in i.modifiers.count to 1 by -1 do deletemodifier i o
else messagebox"至少选择一个物体"
)
on saveobj pressed do
(
if maxfilepath == "" then messagebox"请先保存当前MAX文件"
else
(
selectionarray = (selection as array)
if selection.count == 0 then messagebox"请先选择需要保存/导出的物体"
else(
file_path = getsavepath caption:"保存/导出到..." initialDir:(maxfilepath)
if file_path == undefined do
(
messagebox("文件将保存/导出至 "+maxfilepath)
file_path = maxfilepath
)
createdialog file_op
)
)
)
on import_but pressed do
(
createdialog imp_open
)
on set_pivot pressed do
(
if $ != undefined then $.children.pivot = $.pivot
else messagebox"请选择一个顶端节点"
)
on WP_edit pressed do
(
clearselection()
workingpivot.editmode = not workingpivot.editmode
if workingpivot.editmode == false then WP_edit.caption = "Edit"
else WP_edit.caption = "Editing"
)
on WP_use pressed do
(
clearselection()
workingpivot.usemode = not workingpivot.usemode
if workingpivot.usemode == false then WP_use.caption = "Use"
else WP_use.caption = "Using"
)
on modifiers_off pressed do
for i in selection where i.modifiers.count > 0 do for m in
i.modifiers.count to 1 by -1 do i.modifiers[m].enabledInViews = false
)
createdialog Mytools
再来个有趣的。。没啥作用,但是挺有意思
如图,文字可以根据物体的位置,改变其内容。
首先,这个球有半径选项 名称为 sphere001 文字则为text001
$sphere001.radius.controller = Float_Script()
txt = "$Text001.text = ($Sphere001.pos.x as integer) as string\\n20"
$.radius.controller.script = txt
这个比较稍微需要入门点才能理解,暂时不解释了。觉得有意思可以自己试试效果
本教程由课课家在线学习平台http://www.kokojia.com编辑整理,内容来自网络,非原创,如有涉权,请联系社区管理员协商处理。