Contact Home

Archive for December, 2015

Restricting 2D Camera Zoom and Movement to an Image in Unity C#

Posted on: December 8th, 2015 by admin 8 Comments

The following code will allow you to constrain an orthographic 2D camera, so that it is always contained inside of a background image.

The script will calculate the movement constraints, as well as the max/min zoom values. Regardless of the aspect ratio, the camera will always stay within the image, therefore, never showing any bars on the top or sides of your scene.

The following image, is the demo running, while inside of Scene Mode, to give you an idea of how it works:

2D Camera Example

The source code is all contained in its own class. Read the comments for extra information:

using UnityEngine;

public class Camera2D : MonoBehaviour
    //The background image to use
    public Transform Area;      

    //Sprite details
    private Sprite Sprite;      
    private float PixelUnits;   
    private Vector2 Size;       
    private Vector2 Offset;

    //Camera bounds
    private float Left;
    private float Right;
    private float Top;
    private float Bottom;
    private float MaxZoom;
    private float MinZoom;

    public void Start()
        Sprite = Area.transform.GetComponent<SpriteRenderer>().sprite;


    //Calculate the pixel per unit value is for this sprite
    private void CalculatePixelUnits()
        PixelUnits = Sprite.rect.width / Sprite.bounds.size.x;

    //Calculate the size and offset of the background sprite
    private void CalculateSize()
        Size = new Vector2(Area.transform.localScale.x * Sprite.texture.width / PixelUnits,
                            Area.transform.localScale.y * Sprite.texture.height / PixelUnits);

        Offset = Area.transform.position;

    //Get zoom constraints, and zoom as large as possible for current view
    private void Refresh()
        //calculate current screen ratio
        float w = Screen.width / Size.x;
        float h = Screen.height / Size.y;
        float ratio = w / h;
        float ratio2 = h / w;
        if (ratio2 > ratio)
            MaxZoom = (Size.y / 2);
            MaxZoom = (Size.y / 2);
            MaxZoom /= ratio;

        MinZoom = 1;
        Camera.main.orthographicSize = MaxZoom;


    //Position the camera at the center of the background image
    private void Center()
        //set camera to center of background image
        Vector2 position = Area.transform.position;
        Vector3 camPosition = position;
        Vector3 point = Camera.main.WorldToViewportPoint(camPosition);
        Vector3 delta = camPosition - Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, point.z));
        Vector3 destination = transform.position + delta;
        transform.position = destination;

    //Calculate the max distance the camera can travel
    private void RefreshBounds()
        var vertExtent = Camera.main.orthographicSize;
        var horzExtent = vertExtent * Screen.width / Screen.height;

        Left = horzExtent - Size.x / 2.0f + Offset.x;
        Right = Size.x / 2.0f - horzExtent + Offset.x;
        Bottom = vertExtent - Size.y / 2.0f + Offset.y;
        Top = Size.y / 2.0f - vertExtent + Offset.y;

    public void Update()
        //You would typically hook into Refresh on a screen rotation or aspect ratio change
        //In demo, we call it non stop to demonstrate the camera system 

    public void LateUpdate()
        //Clamp camera inside of our bounds
        Vector3 v3 = transform.position;
        v3.x = Mathf.Clamp(v3.x, Left, Right);
        v3.y = Mathf.Clamp(v3.y, Bottom, Top);
        transform.position = v3;
    public void Zoom(float value)
        Camera.main.orthographicSize += value;
        Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, MinZoom, MaxZoom);

The above script can be attached to a Orthographic Camera. The last thing you need to do is attach a GameObject that contains a SpriteRenderer to the newly added script:

Attach GameObject

You can also download a demo Unity project.