Maya - 聆听动画曲线的变化

Maya - Listen to change in anim curve

我正在寻找一种解决方案来创建一个脚本作业,每当我在图形编辑器中对动画曲线进行任何更改时,就可以说打印一些东西。假设我通过更改值或时间来修改键,或者我修改了它的切线。

在文档中,脚本作业有一个类似 'SelectionChanged' 或 'AttributeChanged' 的事件,因此当其中一个事件为真时,我可以 运行 任何脚本。 但是当我想在图形编辑器中收听动画曲线变化时,我遇到了问题。您知道不使用 Maya API 的任何解决方案吗?在 python 中可行吗?

一切顺利, 彼得

更新:

好的,在细节方面我总是有点麻烦 :)。

(我希望我以正确的方式更新我的问题,但我需要提供代码,因为我仍然有问题)

@Green Cell,我使用了你的代码,但作为内部函数,我想在其他动画曲线上设置键,因此,在 modyfing 'animCurve_A' 之后我有几秒钟的延迟,之后出现“RuntimeError :超出最大递归深度”和“警告:Python 动画回调失败”(但是当我使用例如 setAttr 命令时它有效)。更具体地说,这是我想显示问题的简化代码。

import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
import maya.OpenMayaAnim as OpenMayaAnim

#create empty animation curve and make 2 keyframes
cmds.createNode('animCurveTL', n='animCurve_A') 
cmds.setKeyframe('animCurve_A', t=0, v=0)
cmds.setKeyframe('animCurve_A', t=10, v=10)

#create second empty animation curve
cmds.createNode('animCurveTL', n='animCurve_B') 

#create callback from animCurve_A to drive animCurve_B
def func(mobj_array, client_data):
    for i in range(mobj_array.length()): 
        if OpenMaya.MFnDependencyNode(mobj_array[i]).name() == 'animCurve_A':
            cmds.setKeyframe('animCurve_B', t=0, v=0)

cb = OpenMayaAnim.MAnimMessage.addAnimCurveEditedCallback(func)

有什么线索是我做错了吗?...:(

文档中有一个类似的示例,因此您可以使用 scriptJobattributeChanged 参数:

import maya.cmds as cmds

def func():
    print "TEST"

sj = cmds.scriptJob(attributeChange=['pSphere1.ty', func])

只要 pSphere1 的 translateY 发生变化,就会触发 func。当您在图形编辑器中移动关键点、更改关键点的值和切线的角度时编辑其曲线时,它也会触发。

编辑:

我知道您提到了 'without using Maya API',but there's a way to add a global callback 会在使用 MAnimMessage 对动画曲线进行任何修改时触发。这是一个例子:

import maya.OpenMaya as OpenMaya
import maya.OpenMayaAnim as OpenMayaAnim


# Define a function that the callback will call.
def func(mobj_array, client_data):
    for i in range(mobj_array.length()):  # Need to loop as it may pass multiple curves that are being edited at the same time.
        print OpenMaya.MFnDependencyNode(mobj_array[i]).name()  # Get the curve's name. At this point you can test to see if this is the curve you need to operate on.


cb = OpenMayaAnim.MAnimMessage.addAnimCurveEditedCallback(func)  # Create callback.

# OpenMayaAnim.MAnimMessage.removeCallback(cb)  # Run this to remove the callback.

在函数中您需要添加一个 if 检查以查看它是否是您的自定义曲线。这可以通过名称来完成,或者只是在其上添加自定义属性并检查它是否存在。曲线不需要连接到任何属性,仍然会自行触发。这确实会触发图形编辑器之外的 any 修改,因此 adding/removing/moving 键,在属性编辑器中更改值;但这是有道理的,无论如何都应该预料到。