Unity3D通过一个轴实现平滑更改

Unity3D通过一个轴实现平滑更改,unity3d,Unity3d,我尝试将立方体旋转一个轴90度,如果任何轴处于0位置,所有轴都可以正常工作。但如果任何轴处于任何位置,比如90或-90,他开始无休止地旋转 视频显示它的外观: 有时,当使用欧拉角时,我甚至会得到奇怪的结果,所以我使用四元数 也许在你的固定更新中试试这个 mainCube.transform.rotation = Quaternion.Lerp(mainCube.transform.rotation, Quaternion.Euler(targetEulerAngles), spd); 有时,当

我尝试将立方体旋转一个轴90度,如果任何轴处于0位置,所有轴都可以正常工作。但如果任何轴处于任何位置,比如90或-90,他开始无休止地旋转

视频显示它的外观:


有时,当使用欧拉角时,我甚至会得到奇怪的结果,所以我使用四元数

也许在你的固定更新中试试这个

mainCube.transform.rotation = Quaternion.Lerp(mainCube.transform.rotation, Quaternion.Euler(targetEulerAngles), spd);

有时,当使用欧拉角时,我甚至会得到奇怪的结果,所以我使用四元数

也许在你的固定更新中试试这个

mainCube.transform.rotation = Quaternion.Lerp(mainCube.transform.rotation, Quaternion.Euler(targetEulerAngles), spd);

@joel64在他的回答中所说的绝对正确,但这不是问题所在

问题是您不正确地使用了Lerp。Lerp(a,b,c)的最后一个参数不是速度,而是从0到1的进度,其中c=1表示结果=b,所有其他值介于两者之间。您的代码不断地旋转立方体,从不停止,只是随着时间的推移,它旋转的越来越少

使用欧拉角,由于转换错误,它非常可见,使用四元数,它将不太可见,但旋转从未停止

为了正确地完成这些工作,您需要编写更多的代码。您需要一些变量来保存当前的旋转进度,并且必须记住旋转从何处开始。然后在给定进度的情况下,将立方体从起始位置旋转到目标位置,并增加每帧的进度

哦,如果你希望你的旋转在任何FPS上都是一样的,别忘了deltaTime

最终代码为:

public Vector3 targetEulerAngles;
public float spd = 0.1f;
GameObject mainCube;

private Quaternion startRotation;
private float progress = 0;

public void Awake() {
    mainCube = GameObject.FindGameObjectWithTag("mainCube");
}
public void FixedUpdate() {
    if (progress == 0) startRotation = mainCube.transform.rotation;
    mainCube.transform.rotation = Quaternion.Lerp(startRotation, Quaternion.Euler(targetEulerAngles), progress);
    progress += spd*Time.fixedDeltaTime;
}
public void RotateToLeft() {
    targetEulerAngles = new Vector3(targetEulerAngles.x + 90f, targetEulerAngles.y, targetEulerAngles.z);
    progress = 0;
}
public void RotateToRight() {
    targetEulerAngles = new Vector3(targetEulerAngles.x - 90f, targetEulerAngles.y, targetEulerAngles.z);
    progress = 0;
}
public void RotateToUp() {
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z - 90f);
    progress = 0;
}
public void RotateToDown() {
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z + 90f);
    progress = 0;
}

@joel64在他的回答中所说的绝对正确,但这不是问题所在

问题是您不正确地使用了Lerp。Lerp(a,b,c)的最后一个参数不是速度,而是从0到1的进度,其中c=1表示结果=b,所有其他值介于两者之间。您的代码不断地旋转立方体,从不停止,只是随着时间的推移,它旋转的越来越少

使用欧拉角,由于转换错误,它非常可见,使用四元数,它将不太可见,但旋转从未停止

为了正确地完成这些工作,您需要编写更多的代码。您需要一些变量来保存当前的旋转进度,并且必须记住旋转从何处开始。然后在给定进度的情况下,将立方体从起始位置旋转到目标位置,并增加每帧的进度

哦,如果你希望你的旋转在任何FPS上都是一样的,别忘了deltaTime

最终代码为:

public Vector3 targetEulerAngles;
public float spd = 0.1f;
GameObject mainCube;

private Quaternion startRotation;
private float progress = 0;

public void Awake() {
    mainCube = GameObject.FindGameObjectWithTag("mainCube");
}
public void FixedUpdate() {
    if (progress == 0) startRotation = mainCube.transform.rotation;
    mainCube.transform.rotation = Quaternion.Lerp(startRotation, Quaternion.Euler(targetEulerAngles), progress);
    progress += spd*Time.fixedDeltaTime;
}
public void RotateToLeft() {
    targetEulerAngles = new Vector3(targetEulerAngles.x + 90f, targetEulerAngles.y, targetEulerAngles.z);
    progress = 0;
}
public void RotateToRight() {
    targetEulerAngles = new Vector3(targetEulerAngles.x - 90f, targetEulerAngles.y, targetEulerAngles.z);
    progress = 0;
}
public void RotateToUp() {
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z - 90f);
    progress = 0;
}
public void RotateToDown() {
    targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y, targetEulerAngles.z + 90f);
    progress = 0;
}