相机不能平滑地插入其旋转

时间:2016-10-04 14:12:49

标签: c# unity3d rotation interpolation

我在场景中遇到问题。我正在做的是有两个面板,两个面板都有一个按钮,使用方法名称OnClick()执行RotateCamera()监听器。

Image 1

同样在层次结构中,有MainMenu gameobject附加一个脚本。当我播放场景并点击panel one按钮时,MainCamera按钮与第二个面板的方向成90度角旋转。脚本工作正常,但是当我点击该按钮时,我想平滑地将相机旋转到该面板 - 现在,它正在立即旋转。我不知道我在这个剧本上做错了什么。

public class CameraSmooth : MonoBehaviour {

    private bool check = false;
    private Transform from;
    private Transform to;

    void Start(){
        from = Camera.main.transform;
    }

    void Update(){
        if (to != null) {
            Camera.main.transform.rotation = Quaternion.Slerp (from.rotation, to.rotation, 3 * Time.deltaTime);
        }
    }

    public void RotateCamera(){
        if (!check) {
            Camera.main.transform.Rotate (0,90f,0f);
            to = Camera.main.transform;
            check = true;
        }
        else if (check) {
            Camera.main.transform.rotation = Quaternion.identity;
            to = Camera.main.transform;
            check = false;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

这里的主要问题是您在Camera.main.transform.Rotate()中呼叫RotateCamera()。这会导致旋转立即应用于相机,从而导致您即时旋转。

另一个小错误概念 - 由于Transform是引用类型,fromto实际上总是指向相同的实例(相机的Transform)!最后,3 * Time.deltaTime的值将始终平均大约3/60,并且可能永远不会接近1,这是插值完成所需的。因此,以下行:

Camera.main.transform.rotation = Quaternion.Slerp (from.rotation, to.rotation, 3 * Time.deltaTime);
即使第一个问题得到解决,

也无法做任何事情。

在我看来,情况需要一个不同的解决方案:

  1. 将目标轮换存储在Quaternion变量中,而不是直接在Transform上设置,并跟踪相机的初始旋转

  2. 维护一个跟踪轮换进度的计时器(或者您可以放弃Slerp()并直接应用增量轮换,这也是一种有效的方法)

  3. 以下是我建议的代码更新:

    public class CameraSmooth : MonoBehaviour {
    
        private bool check = false;
        private float rotationProgress = 1;
        private Quaternion initial;
        private Quaternion from;
        private Quaternion to;
    
        void Start(){
            // Cache the starting rotation, so we can calculate rotations relative to it
            initial = Camera.main.transform.rotation;
        }
    
        void Update(){
            if (rotationProgress < 1) {
                rotationProgress += 3 * Time.deltaTime;
                Camera.main.transform.rotation = Quaternion.Slerp (from, to, rotationProgress);
            }
        }
    
        public void RotateCamera(){
            from = Camera.main.transform.rotation;
            rotationProgress = 0;
    
            if (!check) {
                to = initial * Quaternion.Euler(0,90f,0f);
                check = true;
            }
            else if (check) {
                to = initial;
                check = false;
            }
        }
    }
    

    (尚未测试此代码,如果有任何问题,请告诉我。)希望这有帮助!如果您有任何问题,请告诉我们!