【问题标题】:Maya - Listen to change in anim curveMaya - 聆听动画曲线的变化
【发布时间】:2020-10-12 01:30:49
【问题描述】:

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

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

一切顺利, 彼得

更新:

好吧,在细节方面我和往常一样有点麻烦:)。

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

@Green Cell,我使用了您的代码,但作为内部函数,我想在其他 animcurve 上设置键,因此,在修改 '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)

任何线索我做错了什么?... :(

【问题讨论】:

    标签: python scripting maya


    【解决方案1】:

    文档有一个类似的例子,所以你可以使用scriptJobattributeChanged参数:

    import maya.cmds as cmds
    
    def func():
        print "TEST"
    
    sj = cmds.scriptJob(attributeChange=['pSphere1.ty', func])
    

    每当 pSphere1 的 translateY 更改时,这将触发 func。当您在图形编辑器中移动键、更改键的值和更改切线的角度时,它也会在您编辑其曲线时触发。

    编辑:

    我知道您提到了“不使用 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 检查它是否是您的自定义曲线。这可以通过名称来完成,或者只是在其上添加一个自定义属性并检查它是否存在。曲线不需要连接到任何属性,仍然会自行触发。这确实会触发图形编辑器之外的 任何 修改,因此添加/删除/移动键,更改属性编辑器中的值;但这是有道理的,无论如何都应该预料到。

    【讨论】:

    • 感谢您的回答,并且肯定这会起作用,但是我需要更多自定义的东西。问题是我需要让 scriptJob 仅适用于在图形编辑器内对动画曲线所做的更改,该更改未连接到任何属性。我的脚本只使用单个 animcurve 来获取这条曲线上的值,然后使用这些值来创建其他东西 - 我想在每次更改这条特定曲线的键或切线时更新结果。此外,我不想让 scriptJob 在更改时间线时运行,因为这将使用“属性更改”事件发生。谢谢!!
    • 呃,没有。据我所知,没有“仅曲线操作”回调,它需要连接到一个属性才能监听事件。你到底想做什么?也许这种方法不是最好的。如果您只需要将曲线用作界面,那么您可能需要进入PySide,以便您可以使用事件自定义您自己的曲线。
    • 所以我想使用分离的(不连接到任何东西)动画曲线稍后从该曲线中获取点列表。例如,我想获取从 10 到 0 逐渐下降的值。因此,根据曲率,我可以将时间长度划分为 10 个部分,以获得 [10,7,3,1,0.4,0.2,0.1,0.05,0.001] 之类的值价值观。所以下降不是线性的,而是更多的对数。在每次修改这条曲线的键或切线时,我都想刷新列表,这样我就可以使用它们对 vewport 中的对象进行一些计算以查看即时结果......这是否有意义......? :)
    • 我编辑了我的答案,我想这可能就是你想要的。
    • 哇!!我很惊讶它真的有效!似乎这正是我所需要的,但我必须用我的整个代码详细测试它。只是为了确保,如果我想让这个回调只在特定的动画曲线上工作,我应该添加条件,比如: if OpenMaya.MFnDependencyNode(mobj_array[i]).name() == 'myAnimCurve': do something( ) 还是有不同的方法可以更好地做到这一点?干杯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    相关资源
    最近更新 更多