您的代码的旋转部分看起来不错。getAttr -time
但是,您有一个 if/else 块在两种情况下都返回相同的内容,正如@joojaa 所提到的,如果您缓存翻译值,则可以避免。实际上,您应该避免getAttr
并setAttr
完全在表达式中。
相反,直接引用您想要的属性,Maya 将为您创建连接。当您重命名节点等时,这会更快并且更不容易出错。
要缓存平移值并计算位置变化,您可以向节点添加属性并在表达式中使用它们。
假设您有一个名为 wheel 的圆柱体,它围绕其局部 X 旋转,并且是一个名为 control 的组节点的父级:
添加向量属性:control.lastTranslate
添加向量属性:control.deltaTranslate
添加浮点属性:control.distance
这是一个表达式,它将存储平移的变化,然后根据行进的距离旋转轮子。
// When deltaTranslate is calculated, lastTranslate still has its previous value.
control.deltaTranslateX = control.translateX - control.lastTranslateX;
control.deltaTranslateY = control.translateY - control.lastTranslateY;
control.deltaTranslateZ = control.translateZ - control.lastTranslateZ;
control.lastTranslateX = control.translateX;
control.lastTranslateY = control.translateY;
control.lastTranslateZ = control.translateZ;
control.distance = mag(<<control.deltaTranslateX,control.deltaTranslateY,control.deltaTranslateZ>>);
// Get radius from history node (or somewhere) and move the wheel's hub off the floor.
wheel.translateY = polyCylinder1.radius;
// add rotation to the wheel
float $tau = 6.283185307179586;
wheel.rotateX = wheel.rotateX + ( control.distance* -360.0) / (polyCylinder1.radius * $tau );
最好通过动画而不是在视图中拖动节点来测试这种事情。
如果你想让车轮瞄准行驶方向,你可以在 translate + deltaTranslate 处添加一个定位器并连接一个瞄准约束。
例如
aimLocator.translateX = (control.deltaTranslateX / control.distance) + control.translateX;
aimLocator.translateY = (control.deltaTranslateY / control.distance) + control.translateY;
aimLocator.translateZ = (control.deltaTranslateZ / control.distance) + control.translateZ;
除以距离将使偏移正常化。您可能应该检查距离不为零。