Camera follows player but stops at the corners of the map

I want my main camera to follow my player but stop at the corners and edges of the map so that it doesn’t show the void outside of the level. I imagine the formula for this would be, say, for the left edge: Map_minX + camera_width / 2. Except I don’t know which methods do this. I want it so that it is dependent on screen resolution so no matter what device the game is played on (tablet or phone), the camera will be locked to the corners.

My idea was to get the viewport’s dimensions in world units, determine the map’s minmax, and compute from there, but no luck so far.

Attached is a photo of what I want to happen.

Thank you!

There is a tutorial about that made by 3DBuzz, I think it’s the Camera Controller one of the “Creating a 2D game in Unity” series; google it, it’s free on the tube.

This is an old script I made watching that tutorial, it’s should still work once you twick it, but I suggest you to watch that tutorial anyway.
Remember to create a GameObject Camerabounds with a BoxCollider2D and use it in the public field; also you can remove the PixelPerfect part, I don’t remember if it works or not.

using UnityEngine;
using System.Collections;

public class CameraControllerScript : MonoBehaviour
{
    private Transform player;
    private Camera mainCamera;

    public Vector2 margin = new Vector2(1, 1); // If the player stays inside this margin, the camera won't move.
    public Vector2 smoothing = new Vector2(3, 3); // The bigger the value, the faster is the camera.

    public BoxCollider2D cameraBounds;

    private Vector3 min, max;

    public bool isFollowing;


    void Awake()
    {
        player = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
        transform.position = new Vector3(player.position.x, player.position.y, transform.position.z);
    }

    void Start()
    {
        min = cameraBounds.bounds.min;
        max = cameraBounds.bounds.max;
        isFollowing = true;
        mainCamera = GetComponent<Camera>();

        // Camera background Colour.
        if (Application.loadedLevelName != "Town")
            mainCamera.backgroundColor = Color.black;
    }
  
    void Update()
    {
        var x = transform.position.x;
        var y = transform.position.y;

        if (isFollowing)
        {
            if (Mathf.Abs(x - player.position.x) > margin.x)
                x = Mathf.Lerp(x, player.position.x, smoothing.x * Time.deltaTime);

            if (Mathf.Abs(y - player.position.y) > margin.y)
                y = Mathf.Lerp(y, player.position.y, smoothing.y * Time.deltaTime);
        }

        // ortographicSize is the haldf of the height of the Camera.
        var cameraHalfWidth = mainCamera.orthographicSize * ((float)Screen.width / Screen.height);

        x = Mathf.Clamp(x, min.x + cameraHalfWidth, max.x - cameraHalfWidth);
        y = Mathf.Clamp(y, min.y + mainCamera.orthographicSize, max.y - mainCamera.orthographicSize);

        transform.position = new Vector3(x, y, transform.position.z);
    }

    // PixelPerfectScript.
    public static float RoundToNearestPixel(float unityUnits, Camera viewingCamera)
    {
        float valueInPixels = (Screen.height / (viewingCamera.orthographicSize * 2)) * unityUnits;
        valueInPixels = Mathf.Round(valueInPixels);
        float adjustedUnityUnits = valueInPixels / (Screen.height / (viewingCamera.orthographicSize * 2));
        return adjustedUnityUnits;
    }

    void LateUpdate()
    {
        Vector3 newPos = transform.position;
        Vector3 roundPos = new Vector3(RoundToNearestPixel(newPos.x, mainCamera), RoundToNearestPixel(newPos.y, mainCamera), newPos.z);
        transform.position = roundPos;
    }

    public void UpdateBounds()
    {
        min = cameraBounds.bounds.min;
        max = cameraBounds.bounds.max;
    }
}
1 Like

To expand on the above post, what you want to do is impose a limit on the camera position X. Basically: Follow the player if the X is less than XLimit, otherwise, stop moving right. You also probably want to do a minimum X as well, so both sides of the screen are blocked.

Hi, thank you very much. I will look into this and let you know of what happens.

Yes, that’s actually what I want to do but I can’t seem to think of a way to compute for the minimum and maximum X values depending on height/aspect ratio/resolution/whatever is needed, hence this forum post. Thank you.

Oh my bad, I misunderstood what you were asking for.