我对python(20天)很新,但我已经在maya中创建了一些东西,例如拾取器,ik-fk snap以及更多东西。现在我正在尝试创建一个镜像姿势的按钮。
问题是我必须为我的if循环提供2个条件,但maya忽略了第二个条件import maya.cmds as cmds
cmds.select('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
baseOBJ = cmds.ls(sl=True)
cmds.select('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
targetOBJ = cmds.ls(sl=True)
attr = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ', 'IK' ]
for i in range(len (attr) ):
for x in range(len (targetOBJ) ):
if (cmds.attributeQuery(attr[i], node = targetOBJ[x], exists = True) \
and cmds.getAttr(targetOBJ[x] + '.' + attr[i], lock = False)):
newValue = cmds.getAttr(baseOBJ[x] + '.' + attr[i])
cmds.setAttr(baseOBJ[x] + '.' + attr[i], newValue)
else:
pass
错误是:
错误:RuntimeError: file <maya console> line 17: setAttr: The attribute 'arm_lf_FK_ctrl1.translateX' is locked or connected and cannot be modified. #
但在if周期中我写道:cmds.getAttr(targetOBJ[x] + '.' + attr[i], lock = False)
任何提示?
编辑解决方案:
这里是修复的代码
import maya.cmds as cmds
cmds.select('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
baseOBJ = cmds.ls(sl=True)
cmds.select('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
targetOBJ = cmds.ls(sl=True)
attr = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ', 'IK' ]
for i in range(len (attr) ):
for x in range(len (baseOBJ) ):
if (cmds.attributeQuery(attr[i], node = baseOBJ[x], exists = True) \
and cmds.getAttr(baseOBJ[x] + '.' + attr[i], lock = False)):
newValue = cmds.getAttr(baseOBJ[x] + '.' + attr[i])
cmds.setAttr(targetOBJ[x] + '.' + attr[i], newValue)
else:
pass
答案 0 :(得分:2)
您需要指定
cmds.getAttr(item + attribute, lock=True)
即使您正在检查您希望锁定的属性:'lock = true'表示'告诉我锁定状态',不'告诉我锁是否为真'。< / p>
你可以更简单地使用三种常见的python技巧(并且不添加额外的选项,这将只复制你传入的列表)
第一种是使用foreach循环 - 直接从列表中获取值 - 而不是使用数组索引。这是在python中执行循环的标准方法。而不是
for index in range(len(list_of_things)):
do_something(list_of_things[index])
你刚刚做了
for item in list_of_things:
do_something(item)
第二种方法是使用zip()
匹配列表并将它们作为对进行循环:这样可以更容易地编写循环读取干净,同时保持值同步。
最后一件事是使用try...except
并允许发生某些错误而不是预先检查。这是一个常见的python技巧,因为异常并不昂贵,并且生成的代码通常更具可读性。
将这些放在一起你可以做同样的代码:
sources = ('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
targets = ('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
attr = ('.translateX', '.translateY', '.translateZ', '.rotateX', '.rotateY', '.rotateZ', '.IK' )
for source, target in zip(sources, targets):
for attrib in attr:
try:
val = cmds.getAttr(source + attrib)
cmds.setAttr(target + attrib, val)
except Exception as e:
print 'skipped', source + attrib, target + attrib
在这种情况下,如果您向其传递错误对象,错误属性或尝试设置锁定属性,Maya将抛出RuntimeError
。你真的想要比我在这里更加小心,取决于当系统试图做一些不可能的事情时你想做什么。
让您的生活更轻松的最后一招是将您的条件检查与逻辑区分开来。而不是
if (cmds.attributeQuery(attr[i], node = baseOBJ[x], exists = True) \
and cmds.getAttr(baseOBJ[x] + '.' + attr[i], lock = False)):
从长远来看,您可能会发现更容易:
exists, locked = False
try:
exists = cmds.ls(object + attrib) is not None
locked = cmds.getAttr(object + attrib, lock = True)
except:
pass # if the object or attrib is missing, both vals will still be false
if exists and not locked:
#do something
以这种方式编写它可以在出现问题时更容易插入调试打印输出。
答案 1 :(得分:1)
我不知道玛雅,但看起来问题发生在第一个条件本身,因此第二个被忽略。此外,例外情况说运行 setAttr 时出现问题。运行 attributeQuery 时会调用此函数,说 exists = True ,这实际上意味着您将最后添加属性(如果尚未存在)。