Smooth Camera Movement

Sorry for the Jaden Smith title, I am making a game were the camera isn’t attached to the player, and the player makes clicking decisions(The Crucible, act 4) to determine what certain models do/say. That works fine, my issue comes from me wanting every time I click I want the camera to smoothly transition from where it is to a pre determined way point. The problem is it instantly translates to the spot.
Code:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class CameraWaypoints : MonoBehaviour {
    public List<Vector3> posiblepositions;

    public Transform targetPosForRotation;

    public Camera mainCam;

    void Update () {
        if (Input.GetMouseButtonDown(0)) {

            MoveCamera();
        }   
    }

    void MoveCamera()
    {
        int randomSpot = Random.Range(0, posiblepositions.Count);

        mainCam.transform.position = Vector3.Lerp(mainCam.transform.position, posiblepositions[randomSpot], 3f);
        mainCam.transform.LookAt(targetPosForRotation);
    }
}

Its probably because the moveCamera method is only being called on one frame. It is in update which is called every frame but it is restricted with Input.GetMouseButtonDown witch only registers when the mouse is clicked down. The lerp needs multiple frames to interpolate a path over some time.

Try using a bool that is true when you click to use the method in update.

I’d suggest using a tweening framework such as DOTween:
http://dotween.demigiant.com

Also, instead of using Vector3 for your camera possible positions, use transforms instead, this way you can manually place the pre-defined position using emptys, so you can grab them around in the scene view instead of typing the values in the inspector.

You code would be then:

using UnityEngine;
using DG.Tweening;

public class CameraWaypoints : MonoBehaviour
{
    public float transitionDuration = 1.0f;
    public Transform[] posiblepositions;

    public Transform targetPosForRotation;

    public Camera mainCam;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            MoveCamera();
        }
    }

    void MoveCamera()
    {
        int randomSpot = Random.Range(0, posiblepositions.Length);

        mainCam.transform.DOMove(posiblepositions[randomSpot].position, transitionDuration);
        mainCam.transform.DOLookAt(targetPosForRotation.position, transitionDuration);
    }
}

The third parameter in Lerp, t, is a value clamped to [0, 1] that determines how close the result is to the target. The first problem is that you’re fixing it at 3 which would clamp it to 1. This means your object gets to its target immediately. The second problem is that you are are not animating the time.

transform.position = Vector3.Lerp (mainCam.transform.position, possiblepositions[randomSpot], elapsedTime);
elapsedTime += Time.deltaTime;

I’m not sure that much overhead (DOTween API) is necessary for such an easy move. But it would be a considerable improvement if using it for a lot of objects.

Where the overhead would be?
How would it be simpler than that?

I don’t mean a performance overhead at all. It is good software design to keep the codebase as lean as possible. This means using external API’s if and only if they are necessary. In this case, it doesn’t seem to be at all. Your code with DOTween and his with Vector3 look identical; so there isn’t as big a need to use an external API.

Oops, there is a problem with the camera rotation: The camera is looking at the target from the start position, not from the destination position. Here is a fix:

    void MoveCamera()
    {
        int randomSpot = Random.Range(0, posiblepositions.Length);

        var destination = posiblepositions[randomSpot].position;
        var viewDirection = (targetPosForRotation.position - destination).normalized;
        var lookAtRotation = Quaternion.LookRotation(viewDirection);

        mainCam.transform.DOMove(destination, transitionDuration);
        mainCam.transform.DORotateQuaternion(lookAtRotation, transitionDuration);
    }

Me neither.

Agree.

Well, using external tools could help making the code neater.

It looks almost identical, excepted that now it does the expected job.

1 Like