为什么unity相机滚动只在过渡完成后更新场景?

本文关键字:更新 相机 unity 滚动 为什么 | 更新日期: 2023-09-27 18:12:53

我想让我的相机在游戏开始时在场景上滚动。这是附加到我的主相机的代码

using UnityEngine;
using System.Collections;
public class cameraScript : MonoBehaviour {
    public float camYLerpTime = 5000f;
    float camYInitPoint = 950f;
    public float camYEndPoint = 0f;
    float camPosY;
    //float camFieldOfViewStable = 170.5f;
    // Use this for initialization
    void Start () {
        camIntro ();
    }
    // Update is called once per frame
    void LateUpdate () {
        if (transform.position.y!=camYEndPoint) {
            transform.position = new Vector3 (transform.position.x, camPosY, transform.position.z);
        }
    }
    void camIntro()
    {
        camPosY = Mathf.Lerp (camYInitPoint, camYEndPoint, camYLerpTime * Time.deltaTime);
    }
}

然而,我只看到渲染场景完成过渡和相机是在它的最终位置。我做错了什么?

项目设置:2DUnity版本:5.1.2f1

为什么unity相机滚动只在过渡完成后更新场景?

问题

这里的问题是你在

中滥用了Mathf.Lerp()
void camIntro()
{
    camPosY = Mathf.Lerp (camYInitPoint, camYEndPoint, camYLerpTime * Time.deltaTime);
}

提供给Mathf.Lerp()的第三个参数由camYLerpTime * Time.deltaTime给出。这个值到底是多少?好吧,你已经设置了camYLerpTime = 5000f, Time.deltaTime将在~0.0167左右(假设60 FPS,所以1/60)

这意味着Mathf.Lerp()的第三个参数将是:5000 * ~0.0167 = ~83。因此camIntro()的内容可以考虑为:

camPosY = Mathf.Lerp (camYInitPoint, camYEndPoint, 83);

查看Mathf.Lerp()的文档,第三个参数(t)应该在0-1之间,并确定返回值与提供的开始/结束值的接近程度。当t = 0时返回开始值,当t = 1时返回结束值。如果t > 1(就像在这个例子中,t = 83),它被限制为1,因此Mathf.Lerp()将返回结束值(camYEndPoint)。

这就是为什么当代码执行时:

void LateUpdate () {
    if (transform.position.y!=camYEndPoint) {
        transform.position = new Vector3 (transform.position.x, camPosY, transform.position.z);
    }
}

相机立即被抓拍到结束位置,因为这是camPosY之前从Mathf.Lerp()接收到的值。

解决方案

那么,我们如何解决这个问题呢?当Start()被调用时,我们不再调用Mathf.Lerp(),而是在LateUpdate()中调用它,并使用一个变量来跟踪摄像机移动的进度。假设你想让移动持续5秒(而不是5000秒):

using UnityEngine;
using System.Collections;
public class cameraScript : MonoBehaviour {
    public float camYLerpTime = 5f;
    float camYLerpProg = 0;
    float camYInitPoint = 950f;
    public float camYEndPoint = 0f;
    float camPosY;
    //float camFieldOfViewStable = 170.5f;
    // Use this for initialization
    void Start () {
    }
    // Update is called once per frame
    void LateUpdate () {
        if (transform.position.y!=camYEndPoint) {
            camYLerpProg += Time.deltaTime;
            float camPosY = Mathf.Lerp (camYInitPoint, camYEndPoint, camYLerpProg / camYLerpTime);
            transform.position = new Vector3 (transform.position.x, camPosY, transform.position.z);
        }
    }
}
在修改后的代码中,Mathf.Lerp()的第三个参数现在由camYLerpProg / camYLerpTime给出,本质上是(移动时间/最大移动时间),并提供0-1预期范围内的值。

希望这对你有帮助!如果您有任何问题,请告诉我。