平滑地旋转一个对象到一个值
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);
}
我有一个可以在 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);
}