You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maya Python脚本变量未定义报错问题求助

Maya Python脚本变量未定义报错问题求助

嗨,我看了你的脚本,出现NameError的核心问题是变量作用域——你在get_attributes()里定义的newtx、newty这些变量都是局部变量,其他函数(比如apply_attributes())根本访问不到它们。另外脚本里还有几个其他小问题,我一步步给你梳理修改方案:

问题根源分析

  1. 变量作用域问题:get_attributes()内部的变量默认是局部的,函数执行完就销毁了,apply_attributes()找不到这些变量。
  2. 对象名称硬编码:你用固定字符串"newobject"来访问对象,但创建的圆柱名称可能会因为重名被Maya自动加后缀(比如newobject1),而且重命名后这个字符串也会失效。
  3. 无效循环:apply_attributes()里的for axis in ["x","y","z"]循环完全没必要,里面重复设置所有轴的属性,纯粹是冗余代码。
  4. 重命名逻辑错误:cmds.rename(newname)缺少旧对象名称参数,而且没处理重命名后的对象引用。

修改后的完整代码

import maya.cmds as cmds

def spawn_cylinder(*args):
    # 创建圆柱,获取transform节点名称(polyCylinder返回[transform, shape])
    new_object_transform, _ = cmds.polyCylinder(n="newobject")
    # 获取用户输入的所有属性和名称
    attr_values, new_name = get_attributes()
    # 应用属性到新创建的对象
    apply_attributes(new_object_transform, attr_values, new_name)

def get_attributes(*args):
    # 收集平移、旋转、缩放属性
    translate = [
        cmds.floatField("new_x", q=True, v=True),
        cmds.floatField("new_y", q=True, v=True),
        cmds.floatField("new_z", q=True, v=True)
    ]
    rotate = [
        cmds.floatField("new_rx", q=True, v=True),
        cmds.floatField("new_ry", q=True, v=True),
        cmds.floatField("new_rz", q=True, v=True)
    ]
    scale = [
        cmds.floatField("new_sx", q=True, v=True),
        cmds.floatField("new_sy", q=True, v=True),
        cmds.floatField("new_sz", q=True, v=True)
    ]
    # 获取用户输入的新名称
    new_name = cmds.textField("renamefield", q=True, tx=True)
    # 返回收集到的属性值和新名称
    return (translate, rotate, scale), new_name

def apply_attributes(obj_transform, attr_values, new_name):
    translate, rotate, scale = attr_values
    # 设置平移属性
    cmds.setAttr(f"{obj_transform}.translateX", translate[0])
    cmds.setAttr(f"{obj_transform}.translateY", translate[1])
    cmds.setAttr(f"{obj_transform}.translateZ", translate[2])
    # 设置旋转属性
    cmds.setAttr(f"{obj_transform}.rotateX", rotate[0])
    cmds.setAttr(f"{obj_transform}.rotateY", rotate[1])
    cmds.setAttr(f"{obj_transform}.rotateZ", rotate[2])
    # 设置缩放属性
    cmds.setAttr(f"{obj_transform}.scaleX", scale[0])
    cmds.setAttr(f"{obj_transform}.scaleY", scale[1])
    cmds.setAttr(f"{obj_transform}.scaleZ", scale[2])
    
    # 处理重命名:如果用户输入了有效名称才执行
    if new_name.strip():
        try:
            # 重命名并获取最终的对象名称(Maya会自动处理重名)
            obj_transform = cmds.rename(obj_transform, new_name)
            print(f"对象已重命名为: {obj_transform}")
        except Exception as e:
            print(f"重命名失败: {e}")

# 创建UI控件
cmds.floatField("new_x", w=60, v=0)
cmds.floatField("new_y", w=60, v=0)
cmds.floatField("new_z", w=60, v=0)

cmds.floatField("new_rx", w=60, v=0)
cmds.floatField("new_ry", w=60, v=0)
cmds.floatField("new_rz", w=60, v=0)

cmds.floatField("new_sx", w=60, v=1)
cmds.floatField("new_sy", w=60, v=1)
cmds.floatField("new_sz", w=60, v=1)

cmds.textField("renamefield", w=200, placeholderText="输入对象名称")

cmds.button(l="Cylinder", w=60, h=50, c=spawn_cylinder)

关键修改点说明

  1. 变量作用域修复:让get_attributes()返回收集到的所有属性值,在spawn_cylinder()里接收后再传给apply_attributes(),避免用全局变量(全局变量在复杂脚本里容易引发意外问题)。
  2. 对象引用正确传递:创建圆柱时获取真实的transform节点名称(polyCylinder返回的列表第一个元素),并全程传递这个引用,不再用硬编码的"newobject"字符串。
  3. 移除无效循环:删掉了apply_attributes()里无意义的for axis in ["x","y","z"]循环,直接清晰地设置每个属性。
  4. 重命名逻辑修复:cmds.rename需要传入旧名称和新名称,并且捕获重命名后的对象名称(处理Maya自动加后缀的情况),同时增加了空名称判断,避免无效重命名。
  5. 代码可读性优化:把平移、旋转、缩放属性分别打包成列表,让代码更简洁。

现在你可以把修改后的代码复制到Maya脚本编辑器里运行,输入属性值和名称后点击按钮,就能正确创建符合要求的圆柱啦!

备注:内容来源于stack exchange,提问作者MarioFan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 18:24:29