平滑地旋转一个对象到一个值

Rotate an object smoothly to a value

我有一个可以在 z 轴和 y 轴上旋转的飞机控制器。当 up/down 或 left/right 输入 == 0 时,我希望平面旋转重置(再次变为水平)。

经过一些尝试和错误,这有效:

if (Input.GetAxis("Horizontal") == 0.0f && transform.rotation.z != 0f) {
  Vector3 tempRotation = new Vector3();
  tempRotation.z = 0.0f;
  transform.rotation = Quaternion.Euler(tempRotation);
}

但是,这会立即卡入到位。我希望它是一个渐进的轮换。这也会对相机产生负面影响(包括快照)。

我为每个更新周期等尝试了 tempRotation.z -= 0.1f; 之类的东西,但是当它达到 0 时这并没有停止(我不知道为什么):

if (Input.GetAxis("Horizontal") == 0.0f && transform.rotation.z != 0.0f) {
  Vector3 tempRotation = transform.rotation.eulerAngles;
  tempRotation.z = (float) Math.Round(tempRot.z, 1);
  tempRotation.z += 0.1f;
  transform.rotation = Quaternion.Euler(tempRotation);
}

有人知道吗?谢谢。

首先,除非您完全了解四元数,否则不要使用 transform.rotation.z。您可能打算使用 transform.eulerAngles.z.

你可以检查局部右的y分量来确定它是否倾斜,并使用Quaternion.LookRotation找到“重置”旋转,这比使用eulerAngles更安全。

然后,你必须进行轮换。对于非常简单的恒定速度,您可以使用 Quaternion.RotateTowards 向它旋转:

[SerializeField] float resetSpeed;

// ...

if (Input.GetAxis("Horizontal") == 0.0f && !Mathf.Approximately(transform.right.y, 0f))
{
    Quaternion startRot = transform.rotation;
    Quaternion goalRot = Quaternion.LookRotation(transform.forward);
    transform.rotation = Quaternion.RotateTowards(startRot, goalRot, 
            resetSpeed * Time.deltaTime);
}

if (Input.GetAxis("Vertical") == 0.0f && !Mathf.Approximately(transform.forward.y, 0f))
{
    Quaternion startRot = transform.rotation;
    Quaternion goalRot = Quaternion.LookRotation(Vector3.Scale(transform.forward,
            Vector3(1f,0f,1f)), transform.up);
    transform.rotation = Quaternion.RotateTowards(startRot, goalRot, 
            resetSpeed * Time.deltaTime);
}