# Maya 自定义插件添加指南 本指南将帮助你在 NexusLauncher 的 Maya 插件系统中添加自己的工具和插件。 --- ## 📁 目录结构说明 ``` template_plugins/maya/2023/ ├── shelves/ # 工具架文件(.mel 格式) ├── scripts/ # Python/MEL 脚本 ├── plug-ins/ # Maya 插件文件(.py 或 .mll) ├── icons/ # 工具图标 └── README.md # 基础说明文档 ``` --- ## 🎯 添加方式概览 根据你的需求,有三种主要的添加方式: | 方式 | 适用场景 | 难度 | |------|---------|------| | **1. 添加工具架按钮** | 快速添加 Python 脚本工具 | ⭐ 简单 | | **2. 添加 Maya 插件** | 创建 Maya 命令或节点 | ⭐⭐ 中等 | | **3. 添加启动脚本** | 自动执行初始化代码 | ⭐ 简单 | --- ## 方式 1: 添加工具架按钮 ### 适用场景 - 你有一个 Python 脚本工具想要快速访问 - 需要在工具架上添加按钮 - 不需要注册 Maya 命令 ### 步骤 #### 1.1 准备你的 Python 脚本 将你的 Python 脚本放到 `scripts/` 目录: ``` scripts/ ├── userSetup.py # 启动脚本(已存在) ├── nexus_test.py # 示例脚本(已存在) └── my_custom_tool.py # 👈 你的新脚本 ``` **示例脚本** (`my_custom_tool.py`): ```python #!/usr/bin/env python # -*- coding: utf-8 -*- """ 我的自定义工具 """ import maya.cmds as cmds def run_my_tool(): """执行我的工具""" # 你的工具逻辑 cmds.confirmDialog( title='My Tool', message='Hello from my custom tool!', button=['OK'] ) print("[MyTool] Tool executed successfully") def show_ui(): """显示工具界面""" # 如果有 UI,在这里创建 pass ``` #### 1.2 准备图标(可选) 将图标文件放到 `icons/` 目录: ``` icons/ ├── nexus_test.png # 示例图标(已存在) └── my_tool_icon.png # 👈 你的图标(32x32 或 64x64 PNG) ``` > **提示**: 如果没有图标,可以使用文字标签代替 #### 1.3 编辑工具架文件 编辑 `shelves/shelf_NexusLauncher.mel`,在文件末尾的 `}` 之前添加新按钮: ```mel shelfButton -enableCommandRepeat 1 -flexibleWidthType 3 -flexibleWidthValue 32 -enable 1 -width 35 -height 34 -manage 1 -visible 1 -preventOverride 0 -annotation "我的自定义工具 - 点击运行" -enableBackground 0 -backgroundColor 0 0 0 -highlightColor 0.321569 0.521569 0.65098 -align "center" -label "MT" -labelOffset 0 -rotation 0 -flipX 0 -flipY 0 -useAlpha 1 -font "boldLabelFont" -imageOverlayLabel "MT" -overlayLabelColor 1 1 1 -overlayLabelBackColor 0.2 0.8 0.5 0.9 -image "my_tool_icon.png" -image1 "my_tool_icon.png" -style "iconOnly" -marginWidth 0 -marginHeight 1 -command "import my_custom_tool\nmy_custom_tool.run_my_tool()" -sourceType "python" -commandRepeatable 1 -flat 1 ; ``` **关键参数说明**: - `-annotation`: 鼠标悬停时的提示文字 - `-label`: 按钮文字标签(如果没有图标会显示) - `-imageOverlayLabel`: 图标上的文字叠加层 - `-overlayLabelBackColor`: 文字背景颜色 (R G B Alpha) - `-image`: 图标文件名(在 icons/ 目录中) - `-command`: 点击按钮时执行的 Python 代码 #### 1.4 测试 1. 通过 NexusLauncher 启动 Maya 2023 2. 检查 NexusLauncher 工具架是否出现新按钮 3. 点击按钮测试功能 --- ## 方式 2: 添加 Maya 插件 ### 适用场景 - 需要注册自定义 Maya 命令 - 需要创建自定义节点 - 需要更深度的 Maya API 集成 ### 步骤 #### 2.1 创建插件文件 在 `plug-ins/` 目录创建你的插件文件: ``` plug-ins/ ├── nexus_example_plugin.py # 示例插件(已存在) └── my_custom_plugin.py # 👈 你的新插件 ``` **插件模板** (`my_custom_plugin.py`): ```python #!/usr/bin/env python # -*- coding: utf-8 -*- """ 我的自定义 Maya 插件 """ import sys import maya.api.OpenMaya as om def maya_useNewAPI(): """告诉 Maya 使用 Python API 2.0""" pass class MyCustomCommand(om.MPxCommand): """自定义命令类""" kPluginCmdName = 'myCustomCmd' # 命令名称 def __init__(self): om.MPxCommand.__init__(self) @staticmethod def cmdCreator(): return MyCustomCommand() def doIt(self, args): """执行命令""" print(f'[MyPlugin] Custom command executed!') om.MGlobal.displayInfo('My custom plugin is working!') # 在这里添加你的命令逻辑 # 例如:创建对象、修改场景等 def initializePlugin(plugin): """初始化插件""" pluginFn = om.MFnPlugin(plugin, 'YourName', '1.0', 'Any') try: pluginFn.registerCommand( MyCustomCommand.kPluginCmdName, MyCustomCommand.cmdCreator ) print(f'[MyPlugin] Plugin loaded: {MyCustomCommand.kPluginCmdName}') except: sys.stderr.write(f'Failed to register command: {MyCustomCommand.kPluginCmdName}') raise def uninitializePlugin(plugin): """卸载插件""" pluginFn = om.MFnPlugin(plugin) try: pluginFn.deregisterCommand(MyCustomCommand.kPluginCmdName) print(f'[MyPlugin] Plugin unloaded: {MyCustomCommand.kPluginCmdName}') except: sys.stderr.write(f'Failed to deregister command: {MyCustomCommand.kPluginCmdName}') raise ``` #### 2.2 配置自动加载 编辑 `scripts/userSetup.py`,在 `load_nexus_plugins()` 函数中添加你的插件: ```python def load_nexus_plugins(): """Load NexusLauncher plugins""" try: plugin_path = os.environ.get('MAYA_PLUG_IN_PATH', '') if not plugin_path: print("[NexusLauncher] MAYA_PLUG_IN_PATH not set, skipping plugin load") return print(f"[NexusLauncher] MAYA_PLUG_IN_PATH: {plugin_path}") # 要加载的插件列表 plugins_to_load = [ "nexus_example_plugin.py", "my_custom_plugin.py", # 👈 添加你的插件 ] for plugin_file in plugins_to_load: if cmds.pluginInfo(plugin_file, query=True, loaded=True): print(f"[NexusLauncher] Plugin already loaded: {plugin_file}") else: try: cmds.loadPlugin(plugin_file) print(f"[NexusLauncher] ✓ Loaded plugin: {plugin_file}") # 设置为自动加载 cmds.pluginInfo(plugin_file, edit=True, autoload=True) print(f"[NexusLauncher] ✓ Set plugin to auto-load") except Exception as e: print(f"[NexusLauncher] Failed to load plugin {plugin_file}: {e}") except Exception as e: print(f"[NexusLauncher] Error loading plugins: {e}") ``` #### 2.3 测试插件 1. 通过 NexusLauncher 启动 Maya 2023 2. 检查脚本编辑器输出,确认插件已加载 3. 在 Maya 命令行或脚本编辑器中测试命令: ```python import maya.cmds as cmds cmds.myCustomCmd() # 执行你的自定义命令 ``` --- ## 方式 3: 添加启动脚本 ### 适用场景 - 需要在 Maya 启动时自动执行某些操作 - 设置环境变量或全局配置 - 加载第三方库 ### 步骤 #### 3.1 编辑 userSetup.py 在 `scripts/userSetup.py` 文件末尾添加你的初始化代码: ```python def my_custom_startup(): """我的自定义启动函数""" try: print("[MyStartup] Running custom startup code...") # 在这里添加你的启动逻辑 # 例如: # - 设置默认渲染器 # - 加载常用插件 # - 配置工作区 # - 连接到资产管理系统 import maya.cmds as cmds # 示例:设置默认单位为厘米 cmds.currentUnit(linear='cm') print("[MyStartup] ✓ Set default unit to cm") # 示例:设置默认时间单位为 24fps cmds.currentUnit(time='film') print("[MyStartup] ✓ Set default time unit to 24fps") print("[MyStartup] ✓ Custom startup completed") except Exception as e: print(f"[MyStartup] Error during startup: {e}") # 在 Maya 启动完成后执行 cmds.evalDeferred(my_custom_startup) ``` --- ## 🔧 高级技巧 ### 1. 动态重载工具架 如果你在开发过程中频繁修改工具架,可以使用 `RELOAD_SHELF.py` 快速重载: ```python # 在 Maya 脚本编辑器中执行 import sys sys.path.append(r'E:\Zoroot\Dev\NexusLauncher\template\plugins\maya\2023') import RELOAD_SHELF RELOAD_SHELF.reload_shelf() ``` ### 2. 使用相对导入 如果你的工具有多个模块,可以创建包结构: ``` scripts/ ├── my_tool/ │ ├── __init__.py │ ├── core.py │ ├── ui.py │ └── utils.py └── userSetup.py ``` 在工具架按钮中使用: ```mel -command "from my_tool import ui\nui.show_window()" ``` ### 3. 添加菜单项 除了工具架按钮,你还可以在 `userSetup.py` 中添加自定义菜单: ```python def create_custom_menu(): """创建自定义菜单""" try: import maya.cmds as cmds # 检查菜单是否已存在 if cmds.menu('NexusMenu', exists=True): cmds.deleteUI('NexusMenu') # 创建菜单 main_window = mel.eval('$tmpVar=$gMainWindow') custom_menu = cmds.menu( 'NexusMenu', label='NexusTools', parent=main_window, tearOff=True ) # 添加菜单项 cmds.menuItem( label='My Tool', command='import my_custom_tool; my_custom_tool.run_my_tool()', parent=custom_menu ) cmds.menuItem(divider=True, parent=custom_menu) cmds.menuItem( label='About', command='cmds.confirmDialog(title="About", message="NexusTools v1.0")', parent=custom_menu ) print("[NexusLauncher] ✓ Created custom menu") except Exception as e: print(f"[NexusLauncher] Error creating menu: {e}") # 在启动时执行 cmds.evalDeferred(create_custom_menu) ``` ### 4. 调试技巧 **查看环境变量**: ```python import os print(os.environ.get('MAYA_SHELF_PATH')) print(os.environ.get('MAYA_PLUG_IN_PATH')) ``` **检查插件加载状态**: ```python import maya.cmds as cmds print(cmds.pluginInfo(query=True, listPlugins=True)) ``` **查看工具架列表**: ```python import maya.cmds as cmds print(cmds.lsUI(type='shelfLayout')) ``` --- ## 📋 常见问题 ### Q1: 工具架按钮不显示图标? **A**: 检查以下几点: 1. 图标文件是否在 `icons/` 目录中 2. 文件名是否正确(区分大小写) 3. 图标格式是否为 PNG 4. `XBMLANGPATH` 环境变量是否正确设置 ### Q2: Python 脚本找不到模块? **A**: 确保: 1. 脚本在 `scripts/` 目录中 2. `PYTHONPATH` 和 `MAYA_SCRIPT_PATH` 已正确设置 3. 使用 `import` 时不需要包含 `.py` 后缀 ### Q3: 插件加载失败? **A**: 检查: 1. 插件文件语法是否正确 2. 是否包含 `maya_useNewAPI()` 函数(API 2.0) 3. `initializePlugin()` 和 `uninitializePlugin()` 是否正确实现 4. 查看脚本编辑器的错误信息 ### Q4: 修改后没有生效? **A**: 尝试: 1. 完全关闭 Maya 重新启动 2. 使用 `RELOAD_SHELF.py` 重载工具架 3. 检查是否修改了正确版本的文件(2023/2025) ### Q5: 工具架在非 NexusLauncher 启动时也出现? **A**: 这是正常的,因为 Maya 会保存工具架配置。解决方法: - 系统已配置为临时工具架,不会保存到配置文件 - 如果仍然出现,删除 `Documents\maya\2023\prefs\shelves\shelf_NexusLauncher.mel` --- ## 🎓 学习资源 ### Maya Python API - [Maya Python API 2.0 文档](https://help.autodesk.com/view/MAYAUL/2023/ENU/?guid=Maya_SDK_py_ref_index_html) - [Maya Commands 参考](https://help.autodesk.com/cloudhelp/2023/ENU/Maya-Tech-Docs/Commands/index.html) ### MEL 脚本 - [MEL 命令参考](https://help.autodesk.com/cloudhelp/2023/ENU/Maya-Tech-Docs/Commands/index.html) - [工具架按钮参数说明](https://help.autodesk.com/cloudhelp/2023/ENU/Maya-Tech-Docs/Commands/shelfButton.html) --- ## 📝 最佳实践 1. **命名规范** - 使用有意义的名称 - 避免与 Maya 内置命令冲突 - 使用前缀区分自己的工具(如 `nexus_`, `my_`) 2. **错误处理** - 始终使用 try-except 包裹关键代码 - 提供清晰的错误信息 - 使用 `print()` 输出调试信息 3. **代码组织** - 将复杂工具拆分为多个模块 - 使用函数和类组织代码 - 添加文档字符串说明 4. **性能优化** - 避免在启动时执行耗时操作 - 使用 `cmds.evalDeferred()` 延迟执行 - 只加载必要的插件 5. **版本兼容** - 如果支持多个 Maya 版本,注意 API 差异 - 在 `2023/` 和 `2025/` 目录分别维护 - 测试不同版本的兼容性 --- ## 🚀 快速开始示例 ### 完整示例:添加一个"创建立方体"工具 **1. 创建脚本** (`scripts/create_cube_tool.py`): ```python #!/usr/bin/env python # -*- coding: utf-8 -*- """ 创建立方体工具 """ import maya.cmds as cmds def create_custom_cube(): """创建一个自定义立方体""" # 创建立方体 cube = cmds.polyCube(name='CustomCube', width=2, height=2, depth=2)[0] # 设置颜色 cmds.polyColorPerVertex(cube, rgb=(1, 0.5, 0), colorDisplayOption=True) # 移动到原点上方 cmds.move(0, 1, 0, cube) print(f"[CreateCube] Created cube: {cube}") cmds.select(cube) return cube ``` **2. 添加工具架按钮** (编辑 `shelves/shelf_NexusLauncher.mel`): ```mel shelfButton -annotation "Create Custom Cube" -label "Cube" -imageOverlayLabel "CB" -overlayLabelBackColor 0.8 0.5 0.2 0.9 -command "import create_cube_tool\ncreate_cube_tool.create_custom_cube()" -sourceType "python" ; ``` **3. 测试** - 启动 Maya - 点击工具架上的 "CB" 按钮 - 应该会创建一个橙色的立方体 --- ## 📞 获取帮助 如果遇到问题: 1. 检查 Maya 脚本编辑器的错误信息 2. 查看本指南的"常见问题"部分 3. 参考示例插件代码 4. 查阅 Maya 官方文档 --- **祝你开发愉快!** 🎉