2D Camera "Smooth Follow"

Hellow,

I'm trying to make a Camera in Orhtographic and make its focus on y and x plane. But I want to delay the focus as to create a damping motion in the camera movement.

How would I achieve that?

Here is Scott’s answer in C#

using UnityEngine;
using System.Collections;

public class SmoothCamera2D : MonoBehaviour {
	
	public float dampTime = 0.15f;
	private Vector3 velocity = Vector3.zero;
	public Transform target;

	// Update is called once per frame
	void Update () 
	{
		if (target)
		{
			Vector3 point = camera.WorldToViewportPoint(target.position);
			Vector3 delta = target.position - camera.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, point.z)); //(new Vector3(0.5, 0.5, point.z));
			Vector3 destination = transform.position + delta;
			transform.position = Vector3.SmoothDamp(transform.position, destination, ref velocity, dampTime);
		}
	
	}
}

You can use whatever damping function you feel appropriate, but generally, you would repeat:

  1. figure out which way to move
  2. figure out and damp how much to move to keep the same screen position
  3. move

If you threw it into a coroutine with a wait at the start, you could add inital delay and other things, but generally that's it.

Here is a simple damp function that will do generally what you need using Vector3.SmoothDamp:

var dampTime : float = 0.3; //offset from the viewport center to fix damping
private var velocity = Vector3.zero;
var target : Transform;

function Update() {
    if(target) {
        var point : Vector3 = camera.WorldToViewportPoint(target.position);
        var delta : Vector3 = target.position -
                    camera.ViewportToWorldPoint(Vector3(0.5, 0.5, point.z));
        var destination : Vector3 = transform.position + delta;
        transform.position = Vector3.SmoothDamp(transform.position, destination, 
                                                velocity, dampTime);
    }
}

It's been written to work for both orthogonal and perspective cameras. If you want, you can apply some optimization specifically for orthogonal because you wouldn't need to calculate viewport points for an orthogonal camera.

I would like to add, if rigidbody object you folow moves not smoothly (jittery), even if camera moves smooth.
Turn on Interpolation in properties of rigid body.
I couldn’t figure out this for months (

You can read more about this here:

Here is a simple and effective camera smooth follow script with few more options you should see…source github

using UnityEngine;
using System.Collections;
 
public class FollowCamera : MonoBehaviour {
 
	public float interpVelocity;
	public float minDistance;
	public float followDistance;
	public GameObject target;
	public Vector3 offset;
	Vector3 targetPos;
	// Use this for initialization
	void Start () {
		targetPos = transform.position;
	}
	
	// Update is called once per frame
	void FixedUpdate () {
		if (target)
		{
			Vector3 posNoZ = transform.position;
			posNoZ.z = target.transform.position.z;
 
			Vector3 targetDirection = (target.transform.position - posNoZ);
 
			interpVelocity = targetDirection.magnitude * 5f;
 
			targetPos = transform.position + (targetDirection.normalized * interpVelocity * Time.deltaTime); 
 
			transform.position = Vector3.Lerp( transform.position, targetPos + offset, 0.25f);
 
		}
	}
}

This is probably not needed at this point but just in case someone stumbles upon this answer, this is the modified code needed to lock the Y-Axis of the camera, just like an old school platformer. All original code by Scott Kovacs.

//Written by Scott Kovacs via UnityAnswers.com; Oct 5th 2010
//2DCameraFollow - Platformer Script

var dampTime : float = 0.3; //offset from the viewport center to fix damping
private var velocity = Vector3.zero;
var target : Transform;

function Update() {
    if(target) {
        var point : Vector3 = camera.WorldToViewportPoint(target.position);
        var delta : Vector3 = target.position - camera.ViewportToWorldPoint(Vector3(0.5, 0.5, point.z));
        var destination : Vector3 = transform.position + delta;
		
		// Set this to the Y position you want the camera locked to
        destination.y = 0; 
        
        transform.position = Vector3.SmoothDamp(transform.position, destination, velocity, dampTime);
    }
}

I’d like to add that this still made my camera follow all jittery. It was the camera and not the player, but placing it in FixedUpdate() fixed the jitteriness. I’m assuming it’s because FixedUpdate runs on the same steps as Time.deltaTime.

//Written by Scott Kovacs via UnityAnswers.com; Oct 5th 2010
//2DCameraFollow - Platformer Script
 
var dampTime : float = 0.3; //offset from the viewport center to fix damping
private var velocity = Vector3.zero;
var target : Transform;
 
function FixedUpdate() {
    if(target) {
        var point : Vector3 = camera.WorldToViewportPoint(target.position);
        var delta : Vector3 = target.position - camera.ViewportToWorldPoint(Vector3(0.5, 0.5, point.z));
        var destination : Vector3 = transform.position + delta;
 
       // Set this to the Y position you want the camera locked to
        destination.y = 0; 
 
        transform.position = Vector3.SmoothDamp(transform.position, destination, velocity, dampTime);
    }
}

None of these were working for me. All combinations of the solutions posted here still resulted in jerky camera movement. So I attempted my own and came up with something a lot more simple and it works silky smooth:

using UnityEngine;
using System.Collections;

public class SmoothCamera2D : MonoBehaviour {
	
	public float dampTime = 0.15f;
	public Transform target;

	void Update () 
	{
		if (target)
		{
			Vector3 from = transform.position;
			Vector3 to = target.position;
			to.z = transform.position.z;

			transform.position -= (from-to)*dampTime*Time.deltaTime;
		}
	}
}

I don’t have interpolate turned on my player, but it still works like butter for me. Though, i guess turning it on wouldn’t hurt.

I use a much smaller “function” that uses Vector2s
public var player : Transform;
private var lerpTime : float = 5;

function Start () {
	player = GameObject.Find("Player").GetComponent(Transform);
}

function Update () {
	transform.position = Vector2.Lerp(transform.position, player.position, lerpTime * Time.deltaTime);
}

Works great but it’s a bit choppy when the camera is at it’s full distance.

Check this out, it discusses camera smoothing, camera bounds and camera follow: unity 2d camera follow player tutorial