发帖说明:
  1. 发布信息前请阅读华语CG 论坛相关条款声明,一旦发布便表示你已经同意并遵守华语CG条款声明。
  2. 请不用因为不知道主题应该发布在哪板块而担心,华语CG 论坛管理人员会为你解决。
华语CG! » 华语CG 3D技术交流论坛 3D Techiques and Theories 订阅本帖最新内容
翻译一节国外教材,有兴趣学学MAXScript的请进!


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
15 楼 [只看] ·2006-03-29 11:18 |

 

图片:
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
16 楼 [只看] ·2006-03-29 11:18 |

 

3. 首先,我们来解决桌腿排列过齐的问题。在Listener窗口中输入:
for i in $*Table* do rotate i (eulerAngles 0 0 (random -180 180))

 ↑把所有名字里包含关键字table的物体,随便沿Z轴旋转一个角度。

  下面我们来分析一下该句中的最后一部分。MAXScript将每一行代码都视为一个表达式。这意味着每行代码的结尾都会运算出一个数值,同时也表明行内任何一个部分都可以是独立的表达式,只要它可以正确地运算得出某种数值,就可以像直接将一个简单数值放在那里一样使用。

  而当MAXScript得到一个random时,它就会简单地将一个数值结果放进代码中对应的位置上。圆括号的作用在于指出数值间的运算顺序,就如同2+3*2=8而(2+3)*2=10一样。

  现在让我们把每组桌椅稍微移动一下。为了使椅子们保持与对应桌子之间的相对关系,应该将它们一起移动。这可以直接通过脚本实现,只是要用上更多的词汇与好长的一堆代码,然而我们目前的练习是旨在节省时间而且简单易行的,因此可以多点几下鼠标来代替大规模输入代码的麻烦。

 4.用我们熟悉的选择与连接工具,将每组椅子连接到它们对应的桌子上。

 5.连接好之后,在Listener中输入:

for i in $*Table* do move i [(random 5 5),(random 5 5),0]

  这样桌子们的排列就不那么惊人地整齐了。在上一行代码中,我们使用了random表达式来指定了随机的X和Y坐标(因为我们不需要桌子离开地面,所以Z坐标保持为0。)

  有一个值得探讨的问题是我们为何不直接使用这样一个简单些的方法:

move $*Table* [(random 5 5),(random 5 5),0]

  如果使用上面这段代码,那么random表达式实际上只为每个X和Y运算了一次,因此给予每个桌子的移动坐标完全相同,而像前面那样在for循环中使用random,则会在每次运算中生成一次随机数值,因此桌子们各自移动的幅度才会有所区别。不过当然有些时候我们也可能需要后一种方式,所以只需记住它们的不同,根据实际需要选择应用就可以了。(说实话,我觉得那个地砖效果对画面干扰太严重,实际上用第一种方法移动的时候也会让人产生所有桌子同步移动的感觉,因为它们都同时朝相似的方向移动了难以看出差别的一点点,但实际上的确是不同的,不信的话可以把5改成50什么的再回车:)

  接下来轮到椅子们了。摆弄它们的位置需要我们多一点思考过程。大体来讲,它们在离桌子远近距离上的差别应当比其他方向的位移更明显,而现在的情况是每四个椅子围绕着一个桌子,这时要想实现上述效果,我们就需要在每个椅子的局部坐标上来进行move了。

 6.前边我们谈到过,把in coordSys local 放到一个物体运动命令前面就可以使其在局部坐标而不是默认的世界坐标上运动,因此我们输入下面这样的代码:

for i in $*chair* do in coordSys local move i [(random -6 3), (random -1 1),0]

  这样就成功地实现了我们所需的随机排列效果。椅子局部上的X轴就在它们各自朝向桌子的方向上,因此我们将它的随机程度设置得较高,而在Y轴方向上,一个较小的侧向偏移也就可以了,Z轴和前面一样,保持为0。

 7.关于摆弄椅子们的最后一件事和我们最开始对桌子的操作一样,已经心中有数了吧:

  for i in $*chair* do rotate i (eulerAngles 0 0 (random -5 5))

 8.好了,渲染视图,并将结果装载到RAM Player的B通道里面。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
17 楼 [只看] ·2006-03-29 11:19 |

 

图片:
  对比一下,看出区别了吗?微小的混乱排列为场景带来了更多真实感,而且丝毫没有改变场景本身的布局设计“四张桌子,各配四把椅子”,这样才更像是人类的店员而不是机器人们来布置的场景。观众们可能不会看出什么不同,但可以感受到,并且完成这一细节设置仅仅需要我们输入四行代码的时间!

  这个场景的最终效果可以在DVD上找到,cafe_01.max。如果你想进一步改善这一场景,可以用类似的方法移动桌子,或者旋转和缩放一下桌子上的花等等。(没找到,应该是要自己动手栽吧?)

  现在我们是不是有如同方便地使用瑞士军刀似的快感呢?这才只是用了MAXScript宏大词汇库中的几个呢!
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
18 楼 [只看] ·2006-03-29 11:19 |

 

#() 和 [] 与 数列的用法

  数列Array就是一个系列的数据组合。数列的表示方法是把许多数据放进一个圆括号里,数据之间用逗号分隔,括号的前面加上#号,例如:

myArray = #($Box01,$Box02,$Box03)

  上面代码的作用就是定义一个名叫myArray的数列,该数列的内容即为三个box的集合。而当我们需要在其他地方使用这些box时,就可以用这一个数列来代替它们。此外当我们需要单独指定一个数列中的某个对象时,就在数列名后面加上一个方括号并在其中夹进对象的序号,比如在定义了刚才的序列之后输入:

myArray[2]

  我们就得到了类似下面的返回值:

$Box:Box02 @ [6.8000152,13.702519,0.000000]

 ↑即数列myArray中的第二个对象的名称及其所在位置

  还有,输入:

myArray[2].height

  就相当于访问Box02的height 参数。

  在MAXScript中,很多内置的数据结构被组织为数列的形式,并可以在一个for循环的运算中通过指定序号来访问它们。通常我们并不对数列本身进行操作,而是通过for循环在一系列的序号之中进行操作,例如:

for i in 1 to 3 do myArray.height = i*10

 ↑在这行代码中,我们分别在数列序号和目标的高度设置中使用了两个i,因为在每次运算中i的数值增加1,于是Box01的高度被设置为10,而Box02则设置为20,Box03即为30。换句话说——我们用简单的两行代码写出了一个楼梯!

  在MAXScript内置的 meditMaterials数列中,我们可以使用这种技术以random功能为一组物体赋予随机的材质。假设有个场景中需要12个人举起不同的牌子。我们就可以在材质编辑器中的前12个格子中放入不同的牌子材质,选择这些牌子,输入下面的代码:

for i in selection do i.material = meditMaterials[(random 1 12)]

  由于(random 1 12)的运算结果是一个数字, 那么在循环中每次运算都会产生一个随机的数字作为被指定的序号,也就是把材质编辑器中那前12个材质随机分配给所选择的每个牌子了。(然而原文中并没有提到different一词,也就是实际上通常会发生几个牌子共用同一材质,而有的材质没有被使用的情况,另外原文中所用的物体是planes,我难以通过上下文确定它究竟指的是飞机还是平面,但只要用法正确就可以了,物体本身倒是无关紧要的)

  同时,一个物体的修改器堆栈也是以数列形式来访问的,modifiers[1]表示堆栈最顶部的修改器。当你不清楚一个数列到底有多长时,可以用数列里的count属性来查询到里面数据的数量,比如下列用法:

for i in 1 to $.modifiers.count do $.modifiers.Enabled = true

 ↑将所选物体的所有修改器设置为开启状态。

  当我们处理多个物体的修改堆栈时,就有必要将代码分成多行来写(实际上可以一行写完,但过长的单行代码会很难于阅读和除错)。要想输入多行脚本,我们就得打开MAXScript Editor (MAXScript菜单->New Script)而不是Listener了。输入后需要执行该代码时,则使用窗口菜单中的 File -> Evaluate All命令。 多行代码一般写做这样的格式:


for i in geometry where (i.modifiers.count > 0) do
  (
  for j in i.modifiers where ((classOf j == meshsmooth) or (classOf j == TurboSmooth)) do
    (
    j.useRenderIterations = true
    j.renderIterations = 3
    j.iterations = 1
    )
  )


 ↑(看起来挺复杂是吧?如果把它们写成紧密的单行不是更可怕吗)用独立的圆括号和回车断行是为了将代码结构从视觉上分隔开,以便清晰易读。最上面的一个for 循环正是我们一直使用的for i in selection do 操作.而这里面的操作本身又是一个for循环,它使用了字母j而不是i作为变量名,因为i已经被前一个循环中使用了,因此我们必须换一个名称以避免产生冲突。

  上面这段脚本写成通假代码是这样的意思:

for 所有 geometry 带有至少 1 个修改器 do
(
  for 此物体的每个是meshsmooth 或 turbosmooth的修改器 do
   (
   打开该modifier的渲染插值参数
   设置 render iterations为3
   设置 view iterations为1
   )
)

  变量j在循环中为前面i所指定的每个物体的修改器代入数值j。之后它对该修改器是否MeshSmooth或者TurboSmooth进行检查判断,如果它是,就进行do后面指定的操作内容:勾选Render Iterations 的复选框,设置渲染插值为3,视图插值为1。

  注意脚本后面的结束圆括号是两个,为了保证脚本的正确运行,所有圆括号都要对称使用,而上例中将括号缩进的方法就可以帮助我们更清晰地看出圆括号是否已经正确关闭了。

  提示:在MAXScript Editor中,按Ctrl+B 可以选择光标附近(方或圆)括号里所有的字符。而在TextPad中按Ctrl+M则会把光标移动到最近的括号。这是一种修正未关闭括号问题的有力工具。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
19 楼 [只看] ·2006-03-29 11:20 |

 

用"at time" 制作动画

  好极了!在我们开头提到的必备词汇表中,这里是最后一个!使用at time ,我们就可以用前面学过的修改静态参数一样的方法来设置动画了。它的用法是:

at time 帧数

  ↑之后接任何一段MAXScript脚本。如果你的AutoKey自动关键帧按钮已经打开,这行代码就会在所指定的帧上设置一个关键帧。

  提示:使用at time 代码相当于用鼠标将时间滑块拖动到指定帧并执行操作。因此如果界面中的Auto Key按钮并没有开启,就不会生成对应的关键帧。

  在下面的例子中,我们将前面学过的脚本语言之上施展at time的法术,将20个物体飞速地移动起来。当我们要做的动画无需十分严谨的时候(例如作为背景的物体或一次性大规模的物体操作),用MAXScript来做动画就能够节省大量的时间。

用"at time"附魔:闹鬼咖啡屋

1. 打开附带DVD中的 cafe_haunted_start.max。这和前面用过的是同一个咖啡屋,只不过稍微有点变化,出鬼了!

  提示:如果你渲染场景,所看到的光晕是在render effect渲染效果里面设置的。

2.下面的脚本会使咖啡屋里的桌椅诡异地漂浮悬空,但现在还不是设置动画的时候。从菜单里选择MAXScript->Open Script,打开DVD上的 Haunted_furniture.ms,或者把下列代码拷贝到MAXScript Editor窗口中:

for i in $*table* do
  (
for j in 1 to 3 do
  (
  at time ((j*30) + random -10 10) i.position.z = (random 5 30)
  at time ((j*30) + random -10 10) rotate i (eulerangles (random -2 2) (random -2 2) (random -30 30))
  )
)
for i in $*chair* do
  (
  for j in 1 to 3 do
    (
    at time ((j*30) + random -10 10) in coordsys local move i [(random -2 2), (random -2 2), (random -6 6)]
    at time ((j*30) + random -10 10) rotate i (eulerangles (random -2 2) (random -2 2) (random -5 5))
    )
  )
3.打开 Auto Key 自动关键帧按钮(事实上可以用脚本实现,但目前先手动好了)

4.执行上述脚本,即在MAXScript Editor的菜单中选择File->Evaluate All或者按Ctrl+E。

5.关闭Auto Key,再播放动画就可以看到效果了。如果不是很满意,可以Undo两次并重新运行脚本以获得一个不同的随机效果。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
20 楼 [只看] ·2006-03-29 11:20 |

 

图片:
事实上,这个脚本只是我们前面的移动桌椅练习的延伸(又嵌入了for循环和随机数功能),不同的只是(增加了z轴运动)拓展到了三维空间与时间的变化。刚才的脚本用通假代码可以这样理解:

for 所有名称中包含"table"的物体
  (
  at time 大约30,60,90帧 设置关键帧:Z轴位置为5到30的随机值
  at time 大约30,60,90帧 设置关键帧:X,Y轴旋转2度以内,Z轴旋转30度以内
  )
for 所有名称中包含"chaire"的物体
  (
  at time 大约30,60,90帧 设置关键帧:在局部坐标XY轴上移动最多2单位,Z轴运动最多6单位
  at time 大约30,60,90帧 设置关键帧:在局部坐标XY轴上旋转最多2度,Z轴旋转最多5度
  显然,对于具体数值的选择可以依个人审美观点而不同。上面的只是脚本程序结构的演示,可以非常灵活地修改。

  还要记住的是,与粒子动画和修改器驱动动画所不同的是,这种动画方式可以作为手动动画的基础操作——如果我们对上面四个桌子运动中的三个满意而不喜欢最后一个的动作,可以直接进行手动修改。尽管如此,我们如果没有这一脚本的话需要耗费的手工操作要多得多,因此即使脚本操作的结果不十分完美,我们仍然节省了许多手工操作。

  仅仅使用MAXScript中的几个词,我们已经可以批量处理大量物体、设置场景随机化、甚至生成动画!即使我们不再深入研究更多脚本知识,现有的几手已经等于掌握许多灵活而强大的工具了。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
21 楼 [只看] ·2006-03-29 11:21 |

 

创建自定义工具界面

  如果有兴趣的话,接下来我们可以研究一下如何制作带有个性化界面的工具了。本节将讲述一个制作流程,来完成一个简单的工具,并将其设置为既可以当作浮动窗口,又能够嵌入标准工具栏使用。要完成这一目的,我们要了解“概念实证化”脚本编写,在Visual MAXScript可视化编辑器中初步完成界面外观,再将代码并入其中以完成一个整体化的工具。

一个渲染设置管理器——quickDraft(快捷草图)

  从max6时代开始提供的render presets渲染预设功能,是管理多重输出格式与渲染设置的有力工具。而我个人发现,实际上在我的工作中显得最常见而繁琐的操作是:在测试性的渲染时需要提高渲染速度,所以经常打开RenderScene对话框,关闭其中一些渲染设置,并且,很容易在忘记把它们重新打开的情况下就启动一个长时间的正式渲染,结果……真够让我头疼的!

  那么,我是不是应该责怪自己的记性不好,并且坐等软件开发人员在下一个版本的max里面做点改进呢?不!有了MAXScript,我们自己写一个UI工具根本不是什么难事。我们这一节中要写出的脚本称为“快捷草图quickDraft”,我们的目标是——解决上述问题,使我们在工作中往Render Scene 窗口里少跑几趟。

脚本设计

  我们计划的第一步是把一些设计目标写下来。这个过程有点类似于动画制作中的“故事板”步骤。它可以让我们对于初始目标保持关注,以避免沉溺于细节问题。我们的设计目标如下:

为scanline渲染器中一些与速度有关的参数控制开/关状态
得到一种一步到位的方式来完成正式渲染前的准备工作
占用尽可能小的界面——屏幕空间总是宝贵的!
  很显然,前两个目标看起来是需要费一点脑筋的。我们得确定我们的工具是用来设置哪些特定参数的,所以下面我们来列出另一个表:

渲染隐藏几何体
渲染结果窗口
是否储存文件
开启渲染元素
抗锯齿
关闭全部采样器
阴影
区域灯光/阴影改为点光
开启光线追踪
大气效果
渲染效果
位移贴图
视频颜色检查
自动 反射/折射 与 平面镜反射 贴图
  这个表格略显冗长,所以我删去了一些并不十分常用的功能。当然了,这是我自己的工具,我倾向于使它显得更简洁,而有的人可能更喜欢全功能风格的(比如,你可能需要运动模糊开关,或者为Mental ray等渲染插件定义自己的工具)。无论如何,一切都是为了流程服务。

脚本概念实证化

  在把时间投入脚本编写之前,有必要先确认一下通过MAXScript来实现对应功能的可能性,并且将其核心功能草拟出来。开始这一步骤的最好起点是MAXScript参考手册。

1.打开Listener和MAXScript Reference(主菜单Help->MAXScript Reference)

2.我们要做的是渲染器设置工具,所以去参考手册的Search搜索页面,输入 renderer,再点击列出主题,双击Renderers章节……也就是列表中的第一个。

  提示:默认情况下,搜索后显示的页面中会把所有对应关键字显示为高亮。这一功能对于在一个长长的页面中找到特殊关键词是很有用的,不过如果高亮的词过多会显得杂乱无章。使用上面的工具按钮:选项->搜索突出显示关闭,然后刷新页面即可消除它们。(用得着的时候别忘了再打开)

3.搜索结果中所列出的第一个属性名是 renderers.current。把它输入Listener并回车,可以看到MAXScript返回信息: Default_Scanline_Renderer:Default_Scanline_Renderer(如果你当前的渲染器是它的话)

4.将滚动条拉到页面最底部,点击相关连接 Default_Scanline_Renderer : RenderClass.
  这样我们看到的页面上,就列出了默认扫描线渲染器中可以通过MAXScript进行设置的所有属性。其中的一些就是我们想要通过quickDraft实现设置的功能,例如第二项.shadows。

5.打开Render Scene对话框,点击Renderer页,下拉页面直到出现 Shadows复选框,然后在Listener中输入下列脚本并按回车:

renderers.current.shadows = false

  按下回车之后我们看到Shadow复选框立即被清除了(并且,如果把上面的赋值改为true再回车的话就会将其重新勾选)。换句话说,这证明了当我们要在自己的工具中设置Shadow开关时,上面的代码就是我们需要的。

6.接下来我们逐个找出设计草案中所需的各项功能(也就是作者所谓proof-of-concept的过程,把设计理念转化为可用的方案)。有些是在本页手册中已经列出的(.antiAliasing, .enablePixelSampler),而有些则必须到Render Scene Dialog等其他章节去寻找。甚至也有些参数要改为其他格式,因为它们并不属于 renderers.current的子属性.这里我们限于篇幅就不进行过分细致的解释了,但通过查看DVD上的 quickDraft_proof_of_concept.ms 中的代码和注释,大家可以得到足够的参考信息。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
22 楼 [只看] ·2006-03-29 11:21 |

 

图片:
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
23 楼 [只看] ·2006-03-29 11:22 |

 

绘制界面

  现在目标明确、方案可行,到了规划我们工具界面的时间了。有些高手喜欢靠全手工写出界面代码,而我们可以用图6.4中叫做Visual MAXScript的工具,通过简单的拖放式操作来创建界面。

1.在MAXScript菜单中选择 New Script

2.在MAXScript Editor窗口菜单中选择Edit -> New Rollout。注意脚本输入区此时变成了灰色,即无法进行输入了;在Visual MAXScript工具开启时,其他的脚本输入区处于锁定状态。

  提示:可视化脚本工具可以用两种方法来启动,不同的启动方式也会对脚本编辑器产生不同的影响:主菜单中MAXScript -> Visual MAXScript Editor,或者 MAXScript Editor窗口菜单中的 Edit -> Edit Rollout。

  如果我们从主菜单中启动Visual MAXScript,就必须在操作完成后把结果储存为一个.ms文件,然后打开这个文件,将其拷贝/粘贴到自己的脚本中去使用。

  而通过 MAXScript编辑窗口的菜单启动可视化工具,则可以将它与脚本编辑器挂接起来,当你通过菜单File -> Save时,界面代码会直接写到你的脚本中,因此这种方式在工作中显得更加方便。

3.编辑器右边是属性页,它用于显示我们当前所编辑界面对象的属性。现在我们把它的name属性改为quickDraft_rollout,而caption改为quickDraft。其中name是我们用来在脚本中指代工具本身的名字,而caption则是在工具界面上所显示的标题名。

4.接下来还是在Properties页,把下面的width设为111,height设为216,使左边表示界面的区域变得更加紧凑,其大小能够容纳一排复选框及其标题就可以了。

5.在编辑窗口下方的部件工具条上点击复选框图标,在左边灰色界面区拖出一个矩形。这样就建立了一个叫做Checkbox的复选框,同时可以看到右边属性页上所显示的内容变成了该复选框的属性。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
24 楼 [只看] ·2006-03-29 11:22 |

 

图片:
图6.5 点选部件工具,之后在规划窗口内画出复选框。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
25 楼 [只看] ·2006-03-29 11:22 |

 

6.将其名称也就是name属性改为hidden,而caption改为Render Hidden

  提示:界面UI元素的name属性中不可以包含空格,也不能以数字开头。

7.如果caption的内容超出了你画的矩形宽度,用矩形侧边的调节柄将其加宽(或者可以使用中文会短一点)。

8.接下来回到右边的属性页,把height属性设置为14,这是大多数UI元素的一般高度。

9.在编辑窗口菜单中选择File -> Save。即可看到MAXScript Editor窗口中被写入了界面代码,尽管它仍然是灰色状态的。

  提示:没有Undo!可视化脚本编辑器中不提供撤消功能,因此一定要记住时常保存你的UI代码,这样一旦你中途操作失误,就可以关闭并重新打开可视化编辑工具以恢复到之前的版本。

10.接下来建立新的复选框时就不必重画了,点击下方工具条的黑箭头选择工具,选择刚才建立的Render Hidden复选框,按Ctrl+C和Ctrl+V进行复制和粘贴,再把复制品往下拖动到合适的位置,并将其name和caption属性改为rfw和RFW。不必在意两框是否对齐,界面编辑器为我们提供了排列工具来完成对齐界面等修整工作。

11.接下来重复9次上述的粘贴-移动-更名操作,这样我们就有了总共11个复选框,使用下列名称与标题来赋予它们对应的属性:
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
26 楼 [只看] ·2006-03-29 11:22 |

 

表6.3 quickDraft中的复选框工具属性


--------------------------------------------------------------------------------
名称 Name 标题 Caption 中文名

--------------------------------------------------------------------------------
hidden Rendder Hidden 渲染隐藏物体
rfw RFW 渲染窗口
save Save File 保存文件
elements Elements Active 渲染元素
aa Antialiasing 抗锯齿
samp Disable Samp 关闭采样
shad Shadows 阴影
area Area as Point 简化区域灯光
raytrace Raytracing 光线追踪
atmo Atmospherics 大气效果
displace Displacement 位移贴图

--------------------------------------------------------------------------------

  现在我们所有的复选框已经建立和命名完毕,该把它们对齐了。

12.选择菜单File -> Save 来把目前的界面代码写入MAXScript Editor中。这样如果下一步操作结果不令人满意,我们就可以还原到这一步来。

13.使用选择工具(黑箭头)框选所有复选框,然后点击菜单Layout -> Align -> Left 也就是向左侧对齐,然后再Layout -> Space Evenly -> Down 即等距离排列。如果效果不理想就回到上一步,手动调节一下复选框们的位置,再执行对齐命令。

  返回上一步工作的方法是:直接关闭Visual MAXScript Editor,询问保存时选否,再在MAXScript Editor窗口菜单中选择Edit -> Edit Rollout。之后就可以重复上述步骤直到我们把界面元素排列到满意为止。在我自己的版本中,我决定把Area as Point项作为Shadows的子选项,因为如果阴影被关闭,那么Area灯光的开关就没有意义了。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
27 楼 [只看] ·2006-03-29 11:23 |

 

图片:
图6.6 对齐与排列工具帮助我们建立整齐清爽的界面

  提示:你可以通过键盘上的方向箭头来微调界面元素的位置,此外在使用鼠标进行移动操作时,通过按住Shift键可以保持直线方向移动。
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
28 楼 [只看] ·2006-03-29 11:23 |

 

14.当你对界面效果满意之后,选择编辑窗口菜单中File -> Save 来保存结果,关闭Visual MAXScript Editor,再在脚本编辑器的菜单中保存你的脚本为 quickDraft_interface01.ms(其实这一步才是真正落实到硬盘上的保存)。再需要打开Visual MAXScript Editor时,在脚本编辑器上直接按F2 就可以了。图6.6中所显示的界面脚本可以在DVD上找到:quickDraft_interface01.ms。

  从概念上来区分,我们的工具中所设置的参数有两种类型:一种是控制性设置,要随文件保存并且根据不同的项目有所区别;另一种是为渲草图加速而做的临时选项,到正式渲染时几乎都要统一设置的。在图6.6中显示的界面布局中,我在这两种参数的分组之间空了一行,不过如果能有一点更清晰的图形化分隔标记就更好了,下面我们就做这件事。

15.点击Group Box“分组框”工具按钮(就在我们刚才用过的复选框按钮左边),然后用鼠标在两组参数周围各拉出一个框。

16.使用分组框工具的尺寸调节柄来把它们的边缘调整到合适,然后将他们的caption属性分别改为 Render Controls 和 Speed-Ups(或者中文名“渲染设置”和“加速选项”)。图中的界面示例保存在DVD上的quickDraft_interface02.ms
  • 编辑此贴
  • 回复此贴


编号:1224
等级:护卫
发帖:576
精华: 2
在线:67小时
好评:73 点
贡献:13 点
加入时间:
2005-12-05
29 楼 [只看] ·2006-03-29 11:23 |

 

图片:
图6.7 完成的 quickDraft UI 界面

17.使用界面编辑窗口菜单的保存命令来把界面代码写入脚本编辑器,关闭Visual MAXScript窗口,再把脚本保存为 quickDraft_interface02.ms

  非常好!通过Visual MAXScript工具,现在我们已经完成了我们“ 快捷草图”工具的界面设计。现在,到了为界面添加脚本代码,并使其能够在3dsmax中作为工具栏开启的时候了。
  • 编辑此贴
  • 回复此贴