为什么统一摄像头滚动仅在过渡完成后更新场景?

时间:2015-09-16 09:03:42

标签: c# unity3d

我正试图在游戏开始时让我的相机滚动我的场景。这是附在我的主摄像头上的代码

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);
    }
}

但是,我只看到渲染的场景,因为过渡已经完成,相机处于最终位置。我做错了什么?

项目设置:2D Unity版本:5.1.2f1

1 个答案:

答案 0 :(得分:1)

问题

这里的问题是您在

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

您提供给Mathf.Lerp()的第三个参数由camYLerpTime * Time.deltaTime提供。这个值究竟是什么?好吧,你已经设置camYLerpTime = 5000fTime.deltaTime约为0.0167(假设60 FPS,那么1/60)

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

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

查看documentation for 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()

解决方案

那么,我们该如何解决这个问题呢?不要在调用Mathf.Lerp()时调用Start(),而是让我们在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。

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