Mario 2D CameraA Perfect 2D Camera Solution in Unity

Author Waldo
Published November 29, 2019

In this video I show you how to setup a camera to follow your character like Super Mario World.

Video Walkthrough

  • 0:40 - Setting up the scene
  • 1:05 - Explaining how a Mario Camera works
  • 1:42 - Calculating Camera Threshold Boundaries
  • 2:30 - Subtracting by our FollowOffset
  • 3:05 - Drawing Gizmos to outline our threshold box
  • 4:05 - Calculating the distance between our character and the center of the camera
  • 5:35 - Defining the new position for the camera
  • 7:10 - Use Vector3.MoveTowards to move our camera
  • 8:10 - Using RigidBody velocity for camera speed
  • 9:20 - Final Product

Source Code for Player.cs

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

public class CameraFollow : MonoBehaviour{
    public GameObject followObject;
    public Vector2 followOffset;
    public float speed = 3f;
    private Vector2 threshold;
    private Rigidbody2D rb;

    // Start is called before the first frame update
    void Start(){
        threshold = calculateThreshold();
        rb = followObject.GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void FixedUpdate(){
        Vector2 follow = followObject.transform.position;
        float xDifference = Vector2.Distance(Vector2.right * transform.position.x, Vector2.right * follow.x);
        float yDifference = Vector2.Distance(Vector2.up * transform.position.y, Vector2.up * follow.y);

        Vector3 newPosition = transform.position;
        if(Mathf.Abs(xDifference) >= threshold.x){
            newPosition.x = follow.x;
        }
        if(Mathf.Abs(yDifference) >= threshold.y){
            newPosition.y = follow.y;
        }
        float moveSpeed = rb.velocity.magnitude > speed ? rb.velocity.magnitude : speed;
        transform.position = Vector3.MoveTowards(transform.position, newPosition, moveSpeed * Time.deltaTime);
    }
    private Vector3 calculateThreshold(){
        Rect aspect = Camera.main.pixelRect;
        Vector2 t = new Vector2(Camera.main.orthographicSize * aspect.width / aspect.height, Camera.main.orthographicSize);
        t.x -= followOffset.x;
        t.y -= followOffset.y;
        return t;
    }
    private void OnDrawGizmos() {
        Gizmos.color = Color.blue;
        Vector2 border = calculateThreshold();
        Gizmos.DrawWireCube(transform.position, new Vector3(border.x * 2, border.y * 2, 1));
    }
}

This tutorial is sponsored by this community

In order to stick to our mission of keeping education free, our videos and the content of this website rely on the support of this community. If you have found value in anything we provide, and if you are able to, please consider contributing to our Patreon. If you can’t afford to financially support us, please be sure to like, comment and share our content — it is equally as important.

Join The Community

Discussion

Browse Tutorials About