下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922
论坛 >3DMAX >【MaxScript】一些简单的MaxScript教程

【MaxScript】一些简单的MaxScript教程

angela发布于 2015-02-06 16:08查看:2636回复:10

从事了几年游戏美工,自学了一些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编辑整理,内容来自网络,非原创,如有涉权,请联系社区管理员协商处理。























收藏(0)0
查看评分情况

全部评分

此主贴暂时没有点赞评分

总计:0

回复分享
angela  于   2015-02-06 16:09 重新编辑过

共有10条评论

  • 课课家运营团队
  • K哥馆
  • 大萌
  • 953424443
  • Mr ken
  • YUI
  • cappuccino
  • mr jack
  • IT宅男
  • Mright
  • 人生如梦183
  • studing
  • 选择版块:

  • 标题:

  • 内容

  • 验证码:

  • 标题:

  • 内容

  • 选择版块:

移动帖子x

移动到: