如何匹配另一个物体的旋转增量?

How to match another object's rotation delta?

我试图让一个对象与另一个对象的旋转增量相匹配。因此,如果对象 A 绕 Y 轴旋转 90 度,我希望对象 B 也绕 Y 轴旋转 90 度。因为我想每一帧都这样做,所以我保存了两个对象的初始旋转。我试着这样做,基于这个 forum post:

objectB.transform.localRotation = (initialObjectARotation * Quaternion.Inverse(objectA.transform.localRotation)) * initialObjectBRotation;

问题是现在旋转是相反的(我不确定这是不是正确的术语,但是如果我向右旋转 objectA 然后 objectB 向左旋转等等)。我该如何解决这个问题?

如果你有上一帧的B(匹配对象)和A(被匹配的目标)的绝对旋转和A的新绝对旋转,你可以求解B的新绝对旋转解释每个对象沿 局部轴 的 A 差异:

Quaternion oldB; // previous global rotation of subject
Quaternion oldA; // previous global rotation of target
Quaternion newA = transformA.rotation; // current global rotation of target

// solve for new global rotation of subject
Quaternion newB = oldB * Quaternion.Inverse(oldA) * newA;

如果这给了你不喜欢的结果,你可以尝试解释沿全局轴的差异:

// solve for new global rotation of subject
Quaternion newB = newA * Quaternion.Inverse(oldA) * oldB;

最后,如果你真的想要它相对于每个对象父对象的,它会有点复杂,因为它涉及以前的父旋转(绝对),以前的局部对象的旋转,以及 A 的当前绝对旋转为您提供 B 的当前绝对旋转。:

Quaternion oldBParent; // previous global rotation of subject's parent
Quaternion oldBLocal; // previous local rotation of subject
Quaternion oldAParent; // previous global rotation of target's parent
Quaternion oldALocal; // previous local rotation of target

// solve for new global rotation of subject
Quaternion newB = oldBParent * Quaternion.Inverse(oldAParent) * newA 
        * Quaternion.Inverse(oldALocal) * oldBLocal;

请注意,如果没有父级,则父级旋转为Quaternion.identity,相当于全局轴形式。整洁!


当然,一旦您拥有 newB,您只需应用 transformB.rotation = newB; 的新旋转。