2
votes

I'm trying to make my camera scroll over my scene as the game starts. here is the code attached to my main camera

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

However, I only see the rendered scene as transition is finished and the camera is in it's final position. What am I doing wrong?

Project settings: 2D Unity version: 5.1.2f1

1

1 Answers

1
votes

The problem

The issue here is that you're misusing Mathf.Lerp() in

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

The third argument you supply to Mathf.Lerp() is given by camYLerpTime * Time.deltaTime. What exactly is this value? Well, you already set camYLerpTime = 5000f, and Time.deltaTime will be around ~0.0167 (assuming 60 FPS, so 1/60)

That means your third argument for Mathf.Lerp() will be: 5000 * ~0.0167 = ~83. So the contents of camIntro() can be considered to be:

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

Looking at the documentation for Mathf.Lerp(), that third argument (t) should be between 0-1, and determines how close the returned value is to the start/end values supplied. When t = 0, the start value is returned, and when t = 1, the end value is returned. If t > 1 (like in this case, where t = 83), it is clamped to 1, and so Mathf.Lerp() will return the end value (camYEndPoint).

This is why when this code executes:

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

the camera is instantly snapped to the end position, because that was the value camPosY received from Mathf.Lerp() earlier.

The solution

So, how do we fix this? Instead of calling Mathf.Lerp() when Start() is called, let's call it in the LateUpdate() instead, and use a variable to track the progress of the camera movement. Assuming you want the movement to go for 5 seconds (and not 5000 seconds):

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

With this revised code, the third argument of Mathf.Lerp() is now given by camYLerpProg / camYLerpTime, which is essentially (movement time elapsed / maximum movement time) and provides a value in the expected range of 0-1.

Hope this helps! Let me know if you have any questions.