How to add momentum/inertia to Camera

Hi, I’ve recently started using Unity, and implemented a Camera that can be dragged with the mouse. However, the camera immediately stops when the mouse button is no longer pressed, but I want it to go on for a while. I’m not too experienced with Unity’s API yet, so I’m not sure on what to do.

CameraScroll.cs:

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

public class CameraScroll : MonoBehaviour
{
    [SerializeField]
    private Camera mainCamera;
    Vector3 touchStart;
    [SerializeField]
    private Bounds camBounds;
    private Vector3 targetPos;
    private float speed = 2.0f;
    // Start is called before the first frame update
    void Start()
    {
        float height = mainCamera.orthographicSize;
        float width = height * mainCamera.aspect;

        float minX = Globals.worldBounds.min.x + width;
        float maxX = Globals.worldBounds.max.x - width;

        camBounds = new Bounds();
        camBounds.SetMinMax(
            new Vector3(minX, mainCamera.transform.position.y, 0),
            new Vector3(maxX, mainCamera.transform.position.y, 0)
            );
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0)) {
            touchStart = mainCamera.ScreenToWorldPoint(Input.mousePosition);
        }

        if (Input.GetMouseButton(0)) {
            Vector3 direction = touchStart - mainCamera.ScreenToWorldPoint(Input.mousePosition);
            targetPos = mainCamera.transform.position + direction;
            targetPos = GetCameraBounds();

            mainCamera.transform.position = targetPos;
        }
       
    }

    private Vector3 GetCameraBounds() {
        return new Vector3(
            Mathf.Clamp(targetPos.x, camBounds.min.x, camBounds.max.x),
            transform.position.y,
            transform.position.z
        );
    }
}

For context, I have separate scripts for the bounds, which get the bounds from a SpriteRenderer.

Ditch that code! :wink:

Look into Cinemachine: Cinemachine

It’s relatively easy to set up. In your case, all you need is to have a (invisible) GameObject that the user drags around with the mouse. Then set up the Cinemachine virtual camera to use the dragged game object as both LookAt and Follow target.

The LookAt Composer should work well enough to give you some smooth follow. You can set it up in the Inspector alone to follow the object closely if the speed is low, but to have it drag behind if the speed is high while also never losing sight of the object should it get too close to the screen borders.

But if you prefer you could also use a Hard Look At and then have a simple script on the dragged GameObject that maintains its current velocity and when the user let’s go of the object, velocity is decremented to zero over a short time.

using UnityEngine;

public class CameraScroll : MonoBehaviour
{
    Vector3 velocity;

    void Update()
    {
        if (Input.GetMouseButton(0))
            velocity-=new Vector3(Input.GetAxis("Mouse X"),0,Input.GetAxis("Mouse Y"));

        Camera.main.transform.position+=velocity*Time.deltaTime;
        velocity*=0.95f; // friction
    }
}