Maya:Maya角色绑定:骨骼与控制器_2024-07-15_13-59-20.Tex

Maya:Maya角色绑定:骨骼与控制器

Maya基础设置

创建新项目

在开始角色绑定之前,首先需要在Maya中创建一个新的项目。这一步骤确保你的工作在一个干净、有组织的环境中进行,便于管理和追踪文件。

  1. 打开Maya:启动Maya软件。
  2. 选择“文件”菜单:在Maya的主菜单中,选择“文件”。
  3. 创建新场景:点击“新建场景”以清除当前场景中的所有内容。
  4. 设置项目:在“文件”菜单中,选择“设置项目…”。在弹出的对话框中,指定项目的位置,通常是一个专门的文件夹,用于存放所有与项目相关的文件。
  5. 配置项目设置:在项目设置对话框中,你可以配置各种设置,包括场景文件的保存位置、纹理、着色器和其他资源的存储位置。确保这些路径正确无误,以便于后续工作。
你遇到的错误: ``` # Error: TypeError: file <maya console> line 62: Invalid flag 'numberOfColumns' ``` 说明你正在使用的 Maya 版本 **不支持 `treeView` 的 `numberOfColumns` 参数**。 --- ## 🔍 原因分析: - `treeView` 控件从 **Maya 2018 开始支持多列功能(`numberOfColumns`)** - 如果你使用的是 **Maya 2017 或更早版本**,该参数并不存在,因此会报错 - 你希望代码兼容 **Maya 2018 及以上版本**,但当前运行的 Maya 版本可能低于 2018 --- ## ✅ 解决方案:自动检测 Maya 版本并使用兼容方式创建表格 我们可以使用 `maya.mel` 或 `maya.cmds.about` 来获取当前 Maya 的版本,并根据版本号决定是否使用 `treeView` 多列模式,或使用 `gridLayout` + `text` 实现一个兼容的表格。 --- ## ✅ 完整兼容代码(自动检测 Maya 版本,兼容 2017 及以上) ```python # -*- coding: utf-8 -*- from __future__ import print_function, division import maya.cmds as cmds import os # 兼容 Maya 2017 及以下版本的表格实现 try: import maya.mel as mel maya_version = int(mel.eval("getApplicationVersionAsFloat")) except: maya_version = 2017 # 假设默认为 2017 print("Current Maya Version: {}".format(maya_version)) texture_node_map = {} selected_texture = None # 用于兼容的列宽 col1 = 200 col2 = 300 col3 = 150 # Maya 2018+ 使用 treeView if maya_version >= 2018: tree_view_ctrl = "textureTreeView" def update_texture_list(): global texture_node_map, selected_texture selected_texture = None texture_node_map.clear() if cmds.treeView(tree_view_ctrl, exists=True): cmds.treeView(tree_view_ctrl, edit=True, removeAll=True) else: tree_view = cmds.treeView( tree_view_ctrl, parent='textureListLayout', numberOfColumns=3, columnWidth=[(1, col1), (2, col2), (3, col3)], columnAlign=[(1, 'left'), (2, 'left'), (3, 'left')], label=[(1, 'Name'), (2, 'Path'), (3, 'Colorspace')], selectCommand=lambda item: on_texture_selected(item) ) textures_with_info = get_texture_nodes_with_color_space_and_name() for tex, name, path, cs in textures_with_info: item_id = name + path + cs cmds.treeView(tree_view_ctrl, edit=True, addItem=(item_id, "")) cmds.treeView(tree_view_ctrl, edit=True, setColumnLabel=(item_id, 1, name)) cmds.treeView(tree_view_ctrl, edit=True, setColumnLabel=(item_id, 2, path)) cmds.treeView(tree_view_ctrl, edit=True, setColumnLabel=(item_id, 3, cs)) texture_node_map[item_id] = tex else: # Maya 2017 及以下使用 gridLayout + text 模拟表格 table_layout = "textureTableLayout" def update_texture_list(): global texture_node_map texture_node_map.clear() if cmds.layout(table_layout, exists=True): cmds.deleteUI(table_layout) layout = cmds.gridLayout(table_layout, numberOfRows=1, cellWidthHeight=(10, 20), parent="textureListLayout") # 表头 cmds.text(label="Name", align="left", parent=layout, width=col1) cmds.text(label="Path", align="left", parent=layout, width=col2) cmds.text(label="Colorspace", align="left", parent=layout, width=col3) textures_with_info = get_texture_nodes_with_color_space_and_name() for tex, name, path, cs in textures_with_info: item_id = name + path + cs cmds.text(label=name, align="left", parent=layout, width=col1, ann=item_id) cmds.text(label=path, align="left", parent=layout, width=col2, ann=item_id) cmds.text(label=cs, align="left", parent=layout, width=col3, ann=item_id) texture_node_map[item_id] = tex # 点击事件模拟 def on_click_event(ctrl): item_id = cmds.text(ctrl, query=True, ann=True) on_texture_selected(item_id) # 重写 create_custom_color_space_gui 来绑定点击事件 def create_custom_color_space_gui(): window_name = "CustomTextureColorSpaceTool" if cmds.window(window_name, exists=True): cmds.deleteUI(window_name) window = cmds.window(window_name, title="Color Space Tool", widthHeight=(900, 500), resizeToFitChildren=True) main_layout = cmds.columnLayout(adjustableColumn=True, rowSpacing=10) # 表格标题 cmds.text(label="Texture List (Name | Path | Color Space):", height=30, align='left') # 使用 layout 包裹表格 list_layout = cmds.columnLayout('textureListLayout', adjustableColumn=True, parent=main_layout) # 初始化贴图列表 update_texture_list() # 如果是低版本 Maya绑定点击事件 if maya_version < 2018: children = cmds.layout(table_layout, query=True, childArray=True) or [] for ctrl in children: if cmds.control(ctrl, exists=True) and cmds.objectTypeUI(ctrl) == "text": cmds.text(ctrl, edit=True, mouseClickCommand=lambda x, c=ctrl: on_click_event(c)) cmds.setParent('..') # 返回 main_layout refresh_btn = cmds.button(label="Refresh", command=lambda x: update_texture_list()) # 按钮布局 - 6 个色彩空间按钮横向排列 color_button_layout = cmds.rowLayout("colorButtonLayout", numberOfColumns=6, adjustableColumn=True, columnAttach=[(i, 'both', 10) for i in range(1, 7)], parent=main_layout) bg_color = [0.3, 0.6, 1.0] # 创建按钮并命名 cmds.button("colorButton1", label="Raw", backgroundColor=bg_color, command=lambda x, cs='Raw': on_set_color_space("", cs)) cmds.button("colorButton2", label="Utility - Raw", backgroundColor=bg_color, command=lambda x, cs='Utility - Raw': on_set_color_space("", cs)) cmds.button("colorButton3", label="sRGB", backgroundColor=bg_color, command=lambda x, cs='sRGB': on_set_color_space("", cs)) cmds.button("colorButton4", label="ACES - ACEScg", backgroundColor=bg_color, command=lambda x, cs='ACES - ACEScg': on_set_color_space("", cs)) cmds.button("colorButton5", label="Utility - sRGB - Texture", backgroundColor=bg_color, command=lambda x, cs='Utility - sRGB - Texture': on_set_color_space("", cs)) cmds.button("colorButton6", label="Utility - Linear - sRGB", backgroundColor=bg_color, command=lambda x, cs='Utility - Linear - sRGB': on_set_color_space("", cs)) cmds.setParent('..') # 返回 main_layout # 新增按钮:将贴图路径改为文件名 cmds.button(label="Use File Name Only", command=lambda x: set_texture_path_to_file_name_only()) # 显示窗口 cmds.showWindow(window) def get_texture_nodes_with_color_space_and_name(): textures = cmds.ls(type='file') result = [] for tex in textures: try: cs = cmds.getAttr(tex + '.colorSpace') except: cs = u'未设置' try: path = cmds.getAttr(tex + '.fileTextureName') if path: full_path = path tex_name = os.path.basename(path) else: full_path = u'未指定' tex_name = u'未指定' except: full_path = u'获取失败' tex_name = u'获取失败' result.append((tex, tex_name, full_path, cs)) return result def on_texture_selected(item): global selected_texture selected_texture = texture_node_map.get(item) print("Selected Texture Node:", selected_texture) def on_set_color_space(ctrl_name, color_space): global selected_texture if not selected_texture: cmds.confirmDialog(title=u'提示', message=u'请先从列表中选择一个贴图。', button=[u'确定']) return try: cmds.setAttr(selected_texture + '.colorSpace', color_space, type='string') print(u"已将 {} 设置为 {} 色彩空间。".format(selected_texture, color_space)) cmds.confirmDialog(title=u'完成', message=u'已修改 {} 的色彩空间为 {}。'.format(selected_texture, color_space), button=[u'确定']) except Exception as e: cmds.confirmDialog(title=u'错误', message=u'无法设置色彩空间:{}'.format(str(e)), button=[u'确定']) def set_texture_path_to_file_name_only(): textures = cmds.ls(type='file') modified_count = 0 for tex in textures: try: path = cmds.getAttr(tex + '.fileTextureName') if path and os.path.exists(path): filename = os.path.basename(path) cmds.setAttr(tex + '.fileTextureName', filename, type='string') print("已将 {} 的路径设置为: {}".format(tex, filename)) modified_count += 1 else: print("跳过 {}: 路径无效或文件不存在".format(tex)) except Exception as e: print("无法修改 {}: {}".format(tex, str(e))) if modified_count > 0: cmds.confirmDialog(title="完成", message="已修改 {} 个贴图路径为文件名".format(modified_count), button=["确定"]) else: cmds.confirmDialog(title="提示", message="没有贴图路径被修改", button=["确定"]) # 创建 GUI create_custom_color_space_gui() ``` --- ### ✅ 功能说明: | Maya 版本 | 控件 | 功能 | |-----------|------|------| | 2018+ | `treeView` | 支持列拖动、多列、点击事件 | | 2017 及以下 | `gridLayout` + `text` | 模拟表格、支持点击、列对齐 | --- ### ✅ 优势: - ✅ 自动检测 Maya 版本 -Maya 2018+ 使用 `treeView` 实现完整功能 -Maya 2017 及以下使用 `gridLayout` 实现兼容表格 -Python 2 & 3 都兼容(不依赖 `six`) - ✅ 所有内容左对齐,避免错位 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值