在 Maya 中,我可以阻止动画曲线节点读取吗?

In Maya can i block an animation curve node from reading?

我想要实现的是在 Maya 中安装棘轮。 现在我有一个控制器,它的旋转 X 值限制在 0-55 之间。 我在我的控制器和棘轮的旋转 Z 之间创建了一个驱动键,因此当驱动器为 0 时,驱动器为 0,当驱动器为 55 时,驱动器为 60,还有一些中间键。 我想要的是,当动画师将驱动器设置为 55 时,驱动器必须设置为 60,直到现在一切都很好,但是 当动画师将驱动器的值放回 0 时,我希望驱动器 n 的值保持在 60。 所以当驱动程序再次转到 55 时,驱动程序将转到 120,依此类推。 这将重复,直到棘轮转到 360。 我唯一能做的就是用 0-336 的值创建一个 long 属性,所有的事情都会同时发生。所以动画师不需要将驱动程序放回 0。 但这很令人困惑。 我知道驱动键是映射值,所以这是不可避免的,但我该怎么做呢? 我需要动画节点停止的 python 脚本节点?然后重新开始

所以我正在尝试编写一个将在 scriptNode 中的函数,因此每次动画师将值放在锤子的 rotateX 上时都会 运行。从 0—>55 是有效的,但我被困在必须将值从 55—>0 降低的地步。

import maya.cmds as mc
def hammer_C():
RX = mc.getAttr(‘hammer.rotateX’)
RZ = mc.getAttr(‘cylider.rotateZ’)
if RX > 0:
   mc.setAttr(‘cylider.rotateZ’, -RX )
elif RX < 55:
   mc.setAttr(‘cylider.rotateZ’, RZ )
else:
   print ‘TEST’

所以基本上我想知道 Python 中是否有一种方法可以说:当 value_A 从 0 到 55 时,当 value_A 从55 比 0 做点别的事

我不知道玛雅,但我想我明白你需要什么,你正在尝试建模 ratchet device 并通过 5560360你的意思是当前的旋转角度。

我还希望你需要在每 60 度锁定你的棘轮,这意味着一旦它达到 60 度的角度倍数,它应该被锁定以防止向后退到低于该角度程度。在 60 的两个倍数之间,它可能向前和向后。

因此我建议下一个代码,它不是 maya-specific 但它仍然可以让您知道该怎么做并且可以根据您的情况采用。我们可以从这段代码开始,并根据需要改进它。

我知道你对 python 了解不多,为此我还用 one-line 公式(next_driven_angle 的计算)创建了一小段代码,你can also try online (plus accepted final version with maya):

import math
previous_driver_angle = 0.
previous_driven_angle = 0.
for next_driver_angle in [0, 10, 25, 35, 55, 35, 45]:
    next_driven_angle = max(math.floor(previous_driven_angle / 60. + 10 ** -6) * 60., previous_driven_angle + (next_driver_angle - previous_driver_angle) * 60. / 55.)
    print('driver', next_driver_angle, 'driven', next_driven_angle)
    previous_driver_angle = next_driver_angle
    previous_driven_angle = next_driven_angle

上面这段小代码的输出是:

driver 0 driven 0.0
driver 10 driven 10.909090909090908
driver 25 driven 27.272727272727273
driver 35 driven 38.18181818181818
driver 55 driven 60.0
driver 35 driven 60.0
driver 45 driven 70.9090909090909

下一个模拟棘轮随机过程的大代码输出(下面列出):

  0: driver   0.0 driven   0.0 non-locked |   1: driver -33.8 driven   0.0     locked |
  2: driver -17.0 driven  18.4 non-locked |   3: driver   3.5 driven  40.7 non-locked |
  4: driver  34.8 driven  74.9 non-locked |   5: driver  53.9 driven  95.7 non-locked |
  6: driver  90.2 driven 135.3 non-locked |   7: driver  79.0 driven 123.0 non-locked |
  8: driver 103.7 driven 150.0 non-locked |   9: driver  67.3 driven 120.0     locked |
 10: driver  34.9 driven 120.0     locked |  11: driver  22.5 driven 120.0     locked |
 12: driver -13.5 driven 120.0     locked |  13: driver   5.4 driven 140.6 non-locked |
 14: driver -11.9 driven 121.7 non-locked |  15: driver -48.5 driven 120.0     locked |
 16: driver -67.5 driven 120.0     locked |  17: driver -78.0 driven 120.0     locked |
 18: driver -56.0 driven 143.9 non-locked |  19: driver -27.2 driven 175.3 non-locked |
 20: driver -60.2 driven 139.4 non-locked |  21: driver -60.2 driven 139.4 non-locked |
 22: driver -25.5 driven 177.3 non-locked |  23: driver -38.5 driven 163.1 non-locked |
 24: driver -30.8 driven 171.4 non-locked |  25: driver -40.4 driven 161.0 non-locked |
 26: driver  -8.3 driven 196.0 non-locked |  27: driver  -5.0 driven 199.6 non-locked |
 28: driver -25.4 driven 180.0     locked |  29: driver -21.0 driven 184.8 non-locked |
 30: driver   7.3 driven 215.6 non-locked |  31: driver  39.9 driven 251.1 non-locked |
 32: driver   1.3 driven 240.0     locked |  33: driver  24.8 driven 265.6 non-locked |
 34: driver  48.7 driven 291.7 non-locked |  35: driver  71.7 driven 316.8 non-locked |
 36: driver  79.3 driven 325.0 non-locked |  37: driver  54.7 driven 300.0     locked |
 38: driver  73.8 driven 320.8 non-locked |  39: driver  43.5 driven 300.0     locked |
 40: driver   6.6 driven 300.0     locked |  41: driver -29.4 driven 300.0     locked |
 42: driver  -7.7 driven 323.6 non-locked |  43: driver  20.5 driven 354.4 non-locked |
 44: driver -12.0 driven 318.9 non-locked |  45: driver  23.8 driven 358.0 non-locked |
 46: driver  61.8 driven 399.4 non-locked |

下一个代码也可以是run online here.

def Main():
    import math, random, sys

    driven_lock_angle_step = 60.
    driver_to_driven_ratio = 55. / driven_lock_angle_step
    driver_angle = 0.
    driven_angle = 0.

    def SetDriverAngle(new_driver_angle):
        nonlocal driver_angle, driven_angle
        
        driver_angle_delta = new_driver_angle - driver_angle
        driven_angle_delta = driver_angle_delta / driver_to_driven_ratio
        
        nearest_driven_lock_angle = math.floor(driven_angle / driven_lock_angle_step + 10 ** -6) * driven_lock_angle_step
        
        driven_was_locked = driven_angle + driven_angle_delta < nearest_driven_lock_angle
        driven_angle = max(nearest_driven_lock_angle, driven_angle + driven_angle_delta)
        driver_angle += driver_angle_delta
        
        return driven_was_locked
        
    # Emulate Process
    
    forward_prob = 0.6 # Probability of forward move, backward move probability will be 1 - forward_prob
    max_step = 40 # Maximum random jump to do
    max_possible_steps = 1000
    driven_stop_angle = 360.
    outputs_per_line = 2 # Entries per line when printing text
    
    was_locked = False
    random.seed(0)
    for i in range(max_possible_steps):
        sys.stdout.write(
            f'{str(i).rjust(3)}: driver {str(round(driver_angle, 1)).rjust(5)} ' +
            f'driven {str(round(driven_angle, 1)).rjust(5)} ' +
            f'{("locked" if was_locked else "non-locked").rjust(10)} | '
        )
        if (i + 1) % outputs_per_line == 0 or i + 1 >= max_possible_steps or driven_angle >= driven_stop_angle:
            sys.stdout.write('\n')
        if driven_angle >= driven_stop_angle:
            break
        driver_angle_delta = random.random() * max_step * (1. if random.random() < forward_prob else -1.)
        was_locked = SetDriverAngle(driver_angle + driver_angle_delta)
    
Main()