3天学会MaxScript教程之(第一天:开始编写我们的第一个MaxScript)

本文介绍MaxScript的基础知识,包括创建简单物体、使用循环和条件语句进行程序化操作,以及如何利用函数封装逻辑。通过实际案例,如创建一组Box并进行变换,帮助读者快速掌握MaxScript的基本语法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】了解Max Script

这是Max内置的脚本语言,可以很方便用来完成一些程序化或者快速完成一些机械性的操作,比如导入一千个模型,并且按照项目的特定规定,分类分大小分种类导入到不同文件夹下,人来完成这件事情将是非常无聊乏味和低效的。所以使用脚本来批量完成会更有价值。

【2】开始搭建一个我们的编程环境

我习惯了c++的高亮和自动补全,如果叫我用max自带的那个editor来做我会觉得十分痛苦。所以我们需要一个比较好的开发环境

首先下载最新版的max2017 然后再下载微软的VsCode,安装一下语法高亮插件,配置好这两个东西之后就可以开始啦。

【3】从一个小例子创建一个物体开始

首先我们需要创建一个max脚本文件然后把它保存在一个方便找的地方比如桌面。创建的话就单击max左上角的script选项栏然后点击newscript就可以啦,然后用VSCode打开,然后开始编写。

先从创建我们的第一个box开始

效果如下所示

下面来一行一行解释代码的意思

第一行:声明一个mybox的变量 然后创建一个 box对象,它的长宽高分别是20 然后把这个创建好的box对象赋值给变量mybox

第二行:修改这个box的名字为BlueBox

第三行:将box的颜色改为蓝色

第四行:将box的位置设置为 x=0 y=10 z=10

第五行:设置box的缩放为xyz 1.5倍

第六行 给box加上一个修改器,twist,设置修改器twist的angle为30

至此我们就已经学会了如何新建一个脚本 然后创建一个几何图形,然后对它进行纺射变换,给集合体加修改器。

再来做几个例子:

【4】复杂点的程序化思想创建物体,流控制

用循环创建一组box吧

for语句的书写格式和c++有点差别,do为循环体。注意作用域。

尝试一些其他的循环语句

这个是一个while do循环体,也有do while循环。两个的区别就是先执行一次再判断和先判断再执行。

再复杂一点,在循环中加一个if判断

可以看到我在y=300的位置创建了一个box,但是这与y=300的球重叠了,我们再用else语句限制一下

总体逻辑还是非常简单的稍微学过编程的很容易理解。主要还是熟悉一下maxscript的语法。

【5】函数

把逻辑封装在函数里面可以方便调用,我们把上一个例子的逻辑封装一下。一个函数的格式和函数的调用方法从下面的代码能一下子看出来了吧。函数声明除了使用function关键字外,还可以用fn

ydistance:500是函数的参数。:500是初始化这个参数给个默认值。

我们在调用函数的时候可以覆盖那个初始值,如果调用的时候不给新值覆盖则会用默认值。

下面是我覆盖了函数默认参数的效果。覆盖写法和调用如下

使用fn声明函数

【6】完成一个简单的插件

打开3dmax->Scripting->visual maxscriptEditor

这是一个可视化max脚本UI编辑器。我们在面板里创建一个button然后点击这个按钮的events

点击eventhandlers

会弹出一个脚本编辑器面板,这回对这个button进行绑定。然后关闭editeventhandler,然后保存。用vscode打开我们保存的这个ms文件你会看到如下代码

rollout unnamedRollout "Untitled" width:162 height:300
(
    button 'btn1' "Button" pos:[21,29] width:103 height:52 align:#left
    on btn1 pressed  do
        box()
)

效果如下

至此我们已经上手编写max脚本了。后面两天再深入提高!

<think>我们遇到了两个问题:1)图表缺少网格线;2)时间轴上只显示每月的第一天,导致标签过少;3)鼠标悬停在数据点上无法显示提示信息(tooltip)。下面我们逐一解决: ### 问题1:缺少网格线 在Vega中,可以通过在`axes`配置中添加`grid`属性来显示网格线。 ### 问题2:时间轴标签过少 默认情况下,Vega会根据时间尺度自动选择标签间隔。我们可以通过设置`tickCount`或`tickMinStep`来控制标签的密度。例如,设置`"tickCount": "day"`可以按显示标签,但这样可能太密集。我们可以使用`"values": {"signal": "sequence(time(&#39;min&#39;), time(&#39;max&#39;), 1000*60*60*24)"}`来指定每显示一个标签,或者调整步长。 ### 问题3:tooltip无法显示 在之前的代码中,我们将tooltip设置在了`line`标记上,但实际用户可能更希望点在`symbol`(数据点)上显示。此外,Vega中tooltip的显示需要配置`"tooltip"`信号,或者确保在标记的`encode`中正确设置了`tooltip`属性。我们还需要确保在顶层配置中启用了tooltip。 ### 修正后的Vega代码 ```json { "$schema": "https://vega.github.io/schema/vega/v5.json", "autosize": {"type": "fit", "contains": "content", "resize": true}, "data": [ { "name": "source", "url": { "%context%": true, "%timefield%": "Base.CreatedAt", "index": "security_score", "body": { "aggs": { "test_buckets": { "filter": { "terms": { "ScoreType.keyword": ["TotalScore", "impactScore"] } }, "aggs": { "time_buckets": { "date_histogram": { "field": "Base.CreatedAt", "fixed_interval": "1m", "extended_bounds": { "min": {"%timefilter%": "min"}, "max": {"%timefilter%": "max"} }, "min_doc_count": 1 }, "aggs": { "score_sum": { "sum": { "script": { "source": "if(doc[&#39;ScoreType.keyword&#39;].value == &#39;TotalScore&#39;) {return doc[&#39;Score&#39;].value}", "lang": "painless" } } }, "impact_data": { "multi_terms": { "size": 10000, "terms": [ {"field": "CompleteInfo.Base.GeneratorId.keyword"}, {"field": "CompleteInfo.Score.FixTime.keyword"}, {"field": "_id"} ] } } } } } } }, "size": 0 } }, "format": {"property": "aggregations.test_buckets.time_buckets.buckets"} }, { "name": "processed", "source": "source", "transform": [ { "type": "formula", "expr": "max(0, datum.score_sum.value)", "as": "final_score" }, { "type": "formula", "expr": "datum.impact_data.buckets", "as": "impact_data" } ] } ], "scales": [ { "name": "xscale", "type": "time", "domain": {"data": "processed", "field": "key"}, "range": "width" }, { "name": "yscale", "type": "linear", "domain": [0, 100], "range": "height", "nice": true, "zero": true } ], "axes": [ { "orient": "bottom", "scale": "xscale", "title": "Time", "format": "%Y-%m-%d %H:%M", // 显示到分钟 "labelOverlap": true, "tickCount": "day", // 按显示刻度 "grid": true // 添加网格线 }, { "orient": "left", "scale": "yscale", "title": "Security Score", "grid": true // 添加网格线 } ], "marks": [ { "type": "line", "from": {"data": "processed"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "key"}, "y": {"scale": "yscale", "field": "final_score"}, "stroke": {"value": "#32CD32"}, "strokeWidth": {"value": 2} } } }, { "type": "symbol", "from": {"data": "processed"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "key"}, "y": {"scale": "yscale", "field": "final_score"}, "fill": {"value": "#FF3030"}, "size": {"value": 50} }, "update": { "tooltip": { "signal": "{\"时间\": timeFormat(datum.key, &#39;%Y-%m-%d %H:%M&#39;), \"最终分数\": format(datum.final_score, &#39;.2f&#39;), \"事件信息\": datum.impact_data}" } } } } ] } ``` ### 关键修正点: 1. **网格线**: - 在x轴和y轴的配置中增加了`"grid": true`,这样就会绘制网格线。 2. **时间轴标签密度**: - 将x轴的`tickCount`设置为`"day"`,这样会每显示一个刻度标签。同时,将时间格式调整为`"%Y-%m-%d %H:%M"`,这样会显示到分钟。但注意,如果时间跨度很大,每一个标签可能仍然不够,我们可以根据实际时间跨度动态调整。例如,使用`"tickCount": {"signal": "ceil(width/50)"}`来根据宽度自动计算标签数量。 3. **Tooltip显示**: - 将tooltip配置移到了`symbol`标记的`update`部分,这样当鼠标悬停在数据点上时就会显示tooltip。注意,Vega默认会在鼠标悬停时显示`tooltip`属性。 4. **时间格式调整**: - 将x轴的`format`改为`"%Y-%m-%d %H:%M"`,这样时间标签会显示到分钟,更精确。 ### 动态调整刻度数量(可选) 如果时间跨度很大,我们可以动态调整刻度数量以避免重叠。例如,我们可以根据图表的宽度来设置刻度数量: ```json "axes": [ { "orient": "bottom", "scale": "xscale", "title": "Time", "format": "%Y-%m-%d %H:%M", "labelOverlap": true, "tickCount": {"signal": "ceil(width/50)"}, // 每50像素一个刻度 "grid": true }, ... ] ``` ### 注意事项: - 如果时间跨度很大,显示到分钟可能会导致标签过长,可以考虑根据时间跨度动态调整时间格式(例如,超过一周则只显示日期)。 - 事件信息(`impact_data`)是一个数组,直接显示在tooltip中可能不太友好,可以考虑使用`join`函数将其转换为字符串。 例如,修改tooltip的signal: ```json "tooltip": { "signal": "{\"时间\": timeFormat(datum.key, &#39;%Y-%m-%d %H:%M&#39;), \"最终分数\": format(datum.final_score, &#39;.2f&#39;), \"事件信息\": join(datum.impact_data, &#39;, &#39;)}" } ``` ### 最终调整后的tooltip(可选): 如果`impact_data`是一个对象数组,我们可以进一步提取关键信息。但根据原始数据,`impact_data`是一个包含多个字段的桶(buckets)数组。我们可能需要更复杂的处理。这里为了简单,先直接显示。 §§相关问题§§: 1. 如何在Vega中根据时间跨度动态调整时间轴标签格式(如超过一周只显示日期)? 2. 如何自定义Vega的网格线样式(如颜色、虚线)? 3. 在tooltip中如何展示嵌套的JSON数据结构? 4. 如何实现Vega图表的响应式布局(根据容器大小自动调整)?</think>感谢您指出这些问题。我将修复网格线缺失、时间轴标签过少以及tooltip不显示的问题,并提供完整的优化后的Vega代码: ### 优化后的Vega代码 ```json { "$schema": "https://vega.github.io/schema/vega/v5.json", "autosize": {"type": "fit", "contains": "content", "resize": true}, "data": [ { "name": "source", "url": { "%context%": true, "%timefield%": "Base.CreatedAt", "index": "security_score", "body": { "aggs": { "test_buckets": { "filter": { "terms": { "ScoreType.keyword": ["TotalScore", "impactScore"] } }, "aggs": { "time_buckets": { "date_histogram": { "field": "Base.CreatedAt", "fixed_interval": "1m", "extended_bounds": { "min": {"%timefilter%": "min"}, "max": {"%timefilter%": "max"} }, "min_doc_count": 1 }, "aggs": { "score_sum": { "sum": { "script": { "source": "if(doc[&#39;ScoreType.keyword&#39;].value == &#39;TotalScore&#39;) {return doc[&#39;Score&#39;].value}", "lang": "painless" } } }, "impact_data": { "multi_terms": { "size": 10000, "terms": [ {"field": "CompleteInfo.Base.GeneratorId.keyword"}, {"field": "CompleteInfo.Score.FixTime.keyword"}, {"field": "_id"} ] } } } } } } }, "size": 0 } }, "format": {"property": "aggregations.test_buckets.time_buckets.buckets"} }, { "name": "processed", "source": "source", "transform": [ { "type": "formula", "expr": "max(0, datum.score_sum.value)", "as": "final_score" }, { "type": "formula", "expr": "datum.impact_data.buckets", "as": "impact_data" }, { "type": "formula", "expr": "join(datum.impact_data.buckets.map(b => b.key.join(&#39;:&#39;)), &#39;, &#39;)", "as": "impact_info" } ] } ], "scales": [ { "name": "xscale", "type": "time", "domain": {"data": "processed", "field": "key"}, "range": "width" }, { "name": "yscale", "type": "linear", "domain": [0, 100], "range": "height", "nice": true, "zero": true } ], "axes": [ { "orient": "bottom", "scale": "xscale", "title": "Time", "format": "%Y-%m-%d %H:%M", // 显示更详细的时间格式 "labelOverlap": true, "tickCount": {"signal": "ceil(width/50)"}, // 根据宽度动态计算标签数量 "grid": true // 添加网格线 }, { "orient": "left", "scale": "yscale", "title": "Security Score", "grid": true // 添加网格线 } ], "legends": [ { "fill": "color", "title": "Markers", "symbolType": "circle", "encode": { "symbols": { "update": { "fill": {"value": "#FF3030"}, "size": {"value": 50} } } } } ], "marks": [ { "type": "line", "from": {"data": "processed"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "key"}, "y": {"scale": "yscale", "field": "final_score"}, "stroke": {"value": "#32CD32"}, "strokeWidth": {"value": 2} } } }, { "type": "symbol", "from": {"data": "processed"}, "encode": { "enter": { "x": {"scale": "xscale", "field": "key"}, "y": {"scale": "yscale", "field": "final_score"}, "fill": {"value": "#FF3030"}, "size": {"value": 50}, "tooltip": { // 修复tooltip显示 "signal": "{\"时间\": timeFormat(datum.key, &#39;%Y-%m-%d %H:%M&#39;), \"最终分数\": format(datum.final_score, &#39;.2f&#39;), \"事件信息\": datum.impact_info}" } } } } ], "signals": [ { "name": "tooltip", "value": {}, "on": [ {"events": "symbol:mouseover", "update": "datum"}, {"events": "symbol:mouseout", "update": "{}"} ] } ] } ``` ### 关键修复点解释: 1. **网格线添加**: ```json "axes": [ { "grid": true // 添加网格线 } ] ``` - 在x轴和y轴配置中添加 `"grid": true` 参数,启用网格线显示 2. **时间轴标签优化**: ```json "format": "%Y-%m-%d %H:%M", // 显示更详细的时间格式 "tickCount": {"signal": "ceil(width/50)"}, // 根据宽度动态计算标签数量 ``` - 使用更详细的时间格式(包含小时和分钟) - 根据图表宽度动态计算标签数量(每50像素一个标签) - 避免只显示每月第一天的问题 3. **Tooltip修复**: ```json "tooltip": { "signal": "{\"时间\": timeFormat(datum.key, &#39;%Y-%m-%d %H:%M&#39;), \"最终分数\": format(datum.final_score, &#39;.2f&#39;), \"事件信息\": datum.impact_info}" }, "signals": [ { "name": "tooltip", "value": {}, "on": [ {"events": "symbol:mouseover", "update": "datum"}, {"events": "symbol:mouseout", "update": "{}"} ] } ] ``` - 将tooltip配置移到symbol标记中 - 添加信号处理鼠标悬停事件 - 优化impact_data显示(使用join函数转换为字符串) 4. **事件信息格式化**: ```json "transform": [ { "type": "formula", "expr": "join(datum.impact_data.buckets.map(b => b.key.join(&#39;:&#39;)), &#39;, &#39;)", "as": "impact_info" } ] ``` - 将嵌套的impact_data结构转换为易读的字符串格式 - 使用冒号分隔不同字段,逗号分隔不同事件 5. **添加图例**: ```json "legends": [ { "fill": "color", "title": "Markers", "symbolType": "circle" } ] ``` - 添加图例说明红色圆点代表数据点 ### 使用效果: 1. **网格线**:图表将显示水平和垂直网格线 2. **时间轴**:时间标签密度自适应图表宽度,显示完整日期和时间 3. **Tooltip**:鼠标悬停在数据点上会显示详细信息: ``` 时间: 2023-10-05 14:30 最终分数: 85.50 事件信息: event1:fix1:id1, event2:fix2:id2 ``` ### 注意事项: 1. 如果impact_data结构复杂,可能需要进一步调整转换逻辑 2. 时间格式可以根据需要调整(如 `%Y-%m-%d` 只显示日期) 3. 标签密度计算公式 `ceil(width/50)` 可根据实际效果调整除数
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值