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。
答案 0 :(得分:0)
LookRotation
产生的四元数每个都将从恒等旋转旋转到参数指定的旋转。从非身份旋转应用第二个旋转(q1 * q2
所做的操作)可能使其无法满足创建LookRotation
的一个或两个q2
参数。>
使用Vector3.OrthoNormalize
查找与normal
最接近的正交于target.position - transform.position
的向量。您必须处理法线和该方向平行的情况。
然后,使用Quaternion.LookRotation
获得将旋转的forward
和up
指向那些方向的旋转:
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);
一种替代方法是使用LookRotation
朝normal
方向看,并尽可能先向上指向远离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);