Rigidbody.MoveRotation:四元数相乘会引起恒定旋转

时间:2019-06-09 18:20:00

标签: c# unity3d quaternions

Quaternion q1 = Quaternion.LookRotation(Vector3.Cross(transform.right, normal), normal);
Quaternion q2 = Quaternion.LookRotation(target.position - transform.position, normal);

我正在尝试使用两个四元数一起在3D场景中旋转对象,以使对象保持垂直于其下面的地形(q1),并且对象的正面面向目标变换(q2);

FixedUpdate中使用Rigidbody.MoveRotation(q1)Rigidbody.MoveRotation(q2)会使对象旋转到所需的旋转并保持指向该方向。如果我使用Rigidbody.MoveRotation(q1 * q2),它会沿其上轴旋转。

我已经尽力想到了生成q1和q2的所有方法,无论我如何提出这些角度,将它们相乘都会导致旋转问题。

我们是否需要缓存某种旋转增量或某种东西来跟踪距上一帧并进行调整后旋转了多少?

交叉发布于GameDev

1 个答案:

答案 0 :(得分:0)

LookRotation产生的四元数每个都将从恒等旋转旋转到参数指定的旋转。从非身份旋转应用第二个旋转(q1 * q2所做的操作)可能使其无法满足创建LookRotation的一个或两个q2参数。

使用Vector3.OrthoNormalize查找与normal最接近的正交于target.position - transform.position的向量。您必须处理法线和该方向平行的情况。

然后,使用Quaternion.LookRotation获得将旋转的forwardup指向那些方向的旋转:

Vector lookDirection = target.position - transform.position;
if (Mathf.Approximately(1f, Vector3.Dot(normal, lookDirection)))
{
    // normal and lookDirection are parallel
    // Do something reasonable about look direction here.
    // That may mean doing nothing at all!
    return;
}


Vector3.OrthoNormalize(ref normal, ref lookDirection);
Quaternion newRotation = Quaternion.LookRotation(lookDirection, normal);

Rigidbody.MoveRotation(newRotation);

一种替代方法是使用LookRotationnormal方向看,并尽可能先向上指向远离target.position的位置,然后向下倾斜90度:

Vector lookDirection = target.position - transform.position;
if (Mathf.Approximately(1f, Vector3.Dot(normal, lookDirection)))
{
    // normal and lookDirection are parallel
    // Do something reasonable about look direction here.
    // That may mean doing nothing at all!
    return;
}

Quaternion bottomTowardsTarget = Quaternion.LookRotation(normal, -lookDirection);
Quaternion newRotation = bottomTowardsTarget * Quaternion.Euler(-90f,0,0);

Rigidbody.MoveRotation(newRotation);