Keep Top Down 2D camera in bounds of background sprite

Hi.

I’m trying to make a 2D top down camera for my game. I’m a beginner but I managed to solve it for 1 background sprite. My soloution was not a general soloution though and it only works for that particular sprite. I would kindly accept any help of how I would be able to calculate the bounds of any sprite and use it in my script.

This is what I’ve done so far:

using UnityEngine;

using System.Collections;

public class CameraBounds : MonoBehaviour

{

//I write the value of the bound in the inspector

public float rightBound;
public float leftBound;
public float topBound;
public float bottomBound;
private Vector3 pos;

private Transform target;

// Use this for initialization
void Start () 
{
	target = GameObject.FindWithTag("Player").transform;
}

// Update is called once per frame
void Update () 
{
	Debug.Log(pos);

	transform.position = pos;

	if(pos.x != rightBound || pos.x != leftBound || pos.y != topBound || pos.y != bottomBound)
	{
		pos = new Vector3(target.position.x, target.position.y, transform.position.z);
	}

	//Right

	if(pos.x >= rightBound)
	{
		pos.x = rightBound;			
	}

	//Left

	if(pos.x <= leftBound)
	{
		pos.x = leftBound;
	}

	//Top

	if(pos.y >= topBound)
	{
		pos.y = topBound;
	}

	//Bottom

	if(pos.y <= bottomBound)
	{
		pos.y = bottomBound;
	}

}

}

Solved it after the answers I’ve been given + some googling.

Here’s the script I came up with:

private float rightBound;
private float leftBound;
private float topBound;
private float bottomBound;

private Vector3 pos;
private Transform target;
private SpriteRenderer spriteBounds;

// Use this for initialization
void Start () 
{
	float vertExtent = Camera.main.camera.orthographicSize;  
	float horzExtent = vertExtent * Screen.width / Screen.height;

	spriteBounds = GameObject.Find("1 - Background").GetComponentInChildren<SpriteRenderer>();

	target = GameObject.FindWithTag("Player").transform;

	leftBound = (float)(horzExtent - spriteBounds.sprite.bounds.size.x / 2.0f);
	rightBound = (float)(spriteBounds.sprite.bounds.size.x / 2.0f - horzExtent);
	bottomBound = (float)(vertExtent - spriteBounds.sprite.bounds.size.y / 2.0f);
	topBound = (float)(spriteBounds.sprite.bounds.size.y  / 2.0f - vertExtent);

}

// Update is called once per frame
void Update () 
{
	//Debug.Log();

	var pos = new Vector3(target.position.x, target.position.y, transform.position.z);
	pos.x = Mathf.Clamp(pos.x, leftBound, rightBound);
	pos.y = Mathf.Clamp(pos.y, bottomBound, topBound);
	transform.position = pos;
}

void OnLevelWasLoaded()
{
	Start();
}

Helpfull link: Calculating 2D camera bounds - Unity Answers

Thanks for the help guys (Joshpsawyer & robertbu)! I’m glad you took the time to help me out. :slight_smile:

This is what worked for me to get the limits for the camera position:

float camExtentV = _cam.orthographicSize;  
float camExtentH = (camExtentV * Screen.width) / Screen.height;

Bounds levelBounds = LevelBoundsSpriteRenderer.bounds;

float leftBound = levelBounds.min.x + camExtentH;
float rightBound = levelBounds.max.x - camExtentH;
float bottomBound = levelBounds.min.y + camExtentV;
float topBound = levelBounds.max.y - camExtentV;

I needed something like this, but a tiny bit different. My camera had to support zooming, so initialization in Start was not sufficient. Adjusted your sample code to support a camera with dynamic bounds and added the possibility for padding.

using UnityEngine;

[RequireComponent(typeof(Camera))]
public class BoundedCamera : MonoBehaviour
{
    public SpriteRenderer spriteBounds;
    // Pad the bounded area to 'paddingRatio'. Such that 1 means the camera can fully reach the bounds and 0.95 provides a 5% padding on all ends
    public float paddingRatio = 1f;
    private new Camera camera;

    void Start()
    {
        camera = GetComponent<Camera>(); 
    }

    void LateUpdate()
    {
        float verticalExtent = camera.orthographicSize;
        float horizontalExtent = verticalExtent * Screen.width / Screen.height;
        float spriteWidth = spriteBounds.sprite.bounds.size.x / 2.0f;
        float spriteHeight = spriteBounds.sprite.bounds.size.y / 2.0f;

        var leftBound = spriteBounds.transform.position.x + paddingRatio * (horizontalExtent - spriteWidth);
        var rightBound = spriteBounds.transform.position.x + paddingRatio * (spriteWidth - horizontalExtent);
        var bottomBound = spriteBounds.transform.position.y + paddingRatio * (verticalExtent - spriteHeight);
        var topBound = spriteBounds.transform.position.y + paddingRatio * (spriteHeight - verticalExtent);

        var pos = new Vector3(transform.position.x, transform.position.y, transform.position.z);
        pos.x = Mathf.Clamp(pos.x, leftBound, rightBound);
        pos.y = Mathf.Clamp(pos.y, bottomBound, topBound);

        transform.position = pos;
    }
}