MaxScript开发公约
写在前面
这只是个人简单的开发声明和平时制作脚本工具时的一些细节,只是想在对 max 文件做出某些数据修改时尽量能避免和其他开发者的数据发生冲突。
如果你是新人,建议和我一起来,在行业保持一致的默契规则,方便他人也是方便自己。
如果你是老人,请教教我!!!
3dsMax 并没有给物体分配全局唯一 ID 的机制,脚本工具通常用 AppData 数据通道存放标记数据。下面是目前已知的通道占用情况,新增工具前请先避开。
| AppData 通道 | 用途 | 占用工具 |
|---|---|---|
101 ~ 105 | 根骨骼标记 | 动画工具-归零工具 |
-81259732468513268、-9125973246851326 | 场景书签、动画片段 | 书签插件 |
777、77 | 选择集名称、时间轴信息 | 选择集合并(save&loadSelectionSets.mse) |
999 | 简体魔域骨架 ID | C3导出助手 |
1001 | 物体 GUID(镜像工具另占用 1002、1003,历史版本用 100) | 骨骼镜像工具 |
5 | 物体 Name 名字 | — |
813 | render hidden 状态标记 | 渣渣渲屏 |
# AppData
AppData 可以在各种对象上储存字符串类型数据,可随 max 文件保存;复制物体对象不会复制 AppData。
开发文档:Access to MAXWrapper AppData
# AppData:101 ~ 105
根骨骼标记
被 动画工具-归零工具 占用。
# AppData:-81259732468513268
id_ranges = -81259732468513268
id_path = -9125973246851326
getAppData rootnode id_ranges
2
3
4
如上,场景 rootnode 上的这两个数据被书签插件占用,用于保存动画片段。
# AppData:777、77
777、77 这两个数被 save&loadSelectionSets.mse 这个 选择集合并 插件所使用,分别是选择集名称、时间轴信息。
fn AMSS_savenamedsel =
(
for obj in objects do
(
setAppData obj 777 ""
setAppData obj 77 (animationRange.start as string +"|" +animationRange.end as string)
id = getAppData obj 1001
if id == undefined do (
id = genGUID()
setAppData obj 1001 id
)
)
try
(
if getNumNamedselsets() != 0 then
(
for i in 1 to getNumNamedselsets() do
(
a = #()
NamedSelectionSetManager.GetNamedSelSetList &a i
b = makeUniqueArray a
if b.count == 1 and b[1] == undefined do
(
Continue
)
for j in 1 to (getNamedselsetItemcount i) do
(
obj = getNamedselsetItem i j
if isValidNode obj do (
temp_ = getAppData obj 777
if temp_ != undefined or temp_.count > 0 do (
selSetString = temp_ + getNamedselsetName i + "|"
try (setAppData obj 777 selSetString) catch ()
)
)
)
)
)
)catch ()
)
callbacks.addscript #filepresave "AMSS_savenamedsel()" id:#savens
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
如上代码,该脚本在每次保存文件时,都会将【选择集信息】【时间轴信息】【GUID】保存到物体上。
# AppData:999(GUID · 简体魔域骨架ID)
简体魔域骨架ID
和下面的 1001 类似,都是用作物体身份 ID,不过写在根骨骼上,与 1001 也只是字符格式不一样。见 C3导出助手。
# AppData:1001(GUID)
3dsMax 中并没有直接给物体 object 分配 GUID,但很多情况下我们需要一个全局唯一又能被保存的 ID 来识别标记 object。
这里推荐使用 AppData 的 1001 数据通道保存 GUID。
fn set_node_guid node_obj =
(
id = getAppData node_obj 1001
if id == undefined do (id = genGUID())
setAppData node_obj 1001 id
id
)
fn AMSS_GenGUID n =
(
if isValidNode n do
(
id = getAppData n 1001
if id == undefined do (
id = genGUID()
setAppData n 1001 id
)
)
)
callbacks.removescripts id:#saveguid
callbacks.addscript #nodeCreated "AMSS_GenGUID (callbacks.notificationParam())" id:#saveguid
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
目前 1001 这个数据通道只有天晴动作工具组里的骨骼镜像工具用到,用来标记骨骼配对的镜像骨骼。该工具目前占用 1001、1002、1003 三个数据通道,其历史版本曾用数据通道 100 保存镜像数据。
# AppData:5(Name 名字)
相信很多人都有使用过 getNodebyName,即按名字查找物体这个函数。个人十分不建议大量使用该函数,因为物体名字有被改的风险。
但是有些情况下我们不得不使用它,比如从外部导入数据时,只有一个物体名字特征,而数据来源的格式我们也无法控制。
后期再次更新数据时,也只能硬着头皮按名字查找物体,但又不想出现物体被改名、重名而无法正确查找的情况。
这里推荐使用 AppData 的数据通道 5 来保存 Name 名字。
# AppData:813(render hidden)
渣渣渲屏在隐藏无需渲染的物体时做标记,用于事后恢复状态。
