Calculating mouse movement bounds

**EDIT: video: - YouTube **

Hi

I have a scene with a ground plane and an orthographic camera, and the camera is panned using the mouse. However, I don’t want the player to be able to pan outside of the ground plane.

I’ve already calculated the orthographicSize to ensure the camera is correctly zoomed to perfectly fit the width of the plane, however I don’t know how to calculate the boundaries.

My code:

using UnityEngine;
using System.Collections;

public class ZoomPan : MonoBehaviour
{

	public float moveSensitivityX = 10.0f;
	public float moveSensitivityY = 20.0f;
	public bool updateZoomSensitivity = false;
	public float orthoZoomSpeed = 1.0f;
	public float zoomMultiplier = 1f;
	
	private bool isPanning = false;
	
	private float maxZoom;	
	
	void Start()
	{
		
		if((float) Screen.width > (float) Screen.height) //landscape
		{
			Camera.main.orthographicSize = (80f / ((float) Screen.width / (float) Screen.height)) / 2f;
		}
		else //portrait
		{
			Debug.Log("Cannot run game - try restarting in landscape mode");
			UnityEditor.EditorApplication.isPlaying = false;
		}

		Camera.main.transform.position = new Vector3(100f, (float) Mathf.Sqrt(2*(100*100)), -100f);
		
		maxZoom = Camera.main.orthographicSize;

	}
	
	
	private Vector2 startPanPos;
	
	void Update()
	{
		
		if(updateZoomSensitivity)
		{
			moveSensitivityX = Camera.main.orthographicSize / 10.0f;
			moveSensitivityY = Camera.main.orthographicSize / 5.0f;
		}
		
		if(!isPanning && Input.GetMouseButton(0)) //start panning
		{
			//Debug.Log("Panning");
			isPanning = true;
			startPanPos = Input.mousePosition;
		}
		else if(isPanning && !Input.GetMouseButton(0)) //stop panning
		{
			//Debug.Log("Not panning");
			isPanning = false;
		}
		else if(isPanning && Input.GetMouseButton(0)) //panning
		{
			
			Vector2 delta = new Vector2(Input.mousePosition.x - startPanPos.x, Input.mousePosition.y - startPanPos.y);
			
			float posX = delta.x * moveSensitivityX * zoomMultiplier * Time.deltaTime;			
			float posY = delta.y * moveSensitivityY * zoomMultiplier * Time.deltaTime;
			
			Vector3 newPosition = Camera.main.transform.position + new Vector3(-posX, 0, -posX) + new Vector3(posY, 0, -posY); 
			
			//clamp camera position to bounds
			
			startPanPos = Input.mousePosition;
			
		}
		else if(Input.GetAxis("Mouse ScrollWheel") > 0f) //zoom in
		{
			Camera.main.orthographicSize -= orthoZoomSpeed;
			Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, maxZoom / 4, maxZoom);
			zoomMultiplier = Camera.main.orthographicSize / maxZoom;
			
		}
		else if(Input.GetAxis("Mouse ScrollWheel") < 0f) //zoom out
		{
			Camera.main.orthographicSize += orthoZoomSpeed;
			Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, maxZoom / 4, maxZoom);
			zoomMultiplier = Camera.main.orthographicSize / maxZoom;
			
		}
		
	}
	
	
	
	
	
	
	
	public static Bounds OrthographicBounds()
    {
        float ratio = (float)Screen.width / (float)Screen.height;
        floatr height = Camera.main.orthographicSize * 2f;
        Vector3 p = Camera.main.transform.localPosition;
        return new Bounds(new Vector3(p.x, p.y, 0f), new Vector3(height * ratio, height, 2f));
    }

	 static public Vector2 ConstrainRect(Bounds screen, Bounds map)
     {
         return ConstrainRect(screen.min, screen.max, map.min, map.max);
     }
	 
     static public Vector2 ConstrainRect(Vector2 minScreen, Vector2 maxScreen, Vector2 minMap, Vector2 maxMap)
     {
         var offset = Vector2.zero;
         var screenWidth = maxScreen.x - minScreen.x;
         var screenHeight = maxScreen.y - minScreen.y;
         var mapWidth = maxMap.x - minMap.x;
         var mapHeight = maxMap.y - minMap.y;
         if (screenWidth > mapWidth)
         {
             var diff = screenWidth - mapWidth;
             minMap.x -= diff;
             maxMap.x += diff;
         }
         if (screenHeight > mapHeight)
         {
             var diff = screenHeight - mapHeight;
             minMap.y -= diff;
             maxMap.y += diff;
         }
         if (minScreen.x < minMap.x) offset.x += minMap.x - minScreen.x;
         if (maxScreen.x > maxMap.x) offset.x -= maxScreen.x - maxMap.x;
         if (minScreen.y < minMap.y) offset.y += minMap.y - minScreen.y;
         if (maxScreen.y > maxMap.y) offset.y -= maxScreen.y - maxMap.y;
         return offset;
     }
	
}

public static class CameraExtensions
{
public static Bounds OrthographicBounds(this Camera camera)
{
var ratio = (float)Screen.width / (float)Screen.height;
var height = camera.orthographicSize * 2f;
var p = camera.transform.localPosition;
return new Bounds(new Vector3(p.x, p.y, 0f), new Vector3(height * ratio, height, 2f));
}
}

Pass your camera bounds and mesh bounds into something like this:

	static public Vector2 ConstrainRect(Bounds screen, Bounds map)
	{
		return ConstrainRect(screen.min, screen.max, map.min, map.max);
	}
	static public Vector2 ConstrainRect(Vector2 minScreen, Vector2 maxScreen, Vector2 minMap, Vector2 maxMap)
	{
		var offset = Vector2.zero;
		var screenWidth = maxScreen.x - minScreen.x;
		var screenHeight = maxScreen.y - minScreen.y;
		var mapWidth = maxMap.x - minMap.x;
		var mapHeight = maxMap.y - minMap.y;
		if (screenWidth > mapWidth)
		{
			var diff = screenWidth - mapWidth;
			minMap.x -= diff;
			maxMap.x += diff;
		}
		if (screenHeight > mapHeight)
		{
			var diff = screenHeight - mapHeight;
			minMap.y -= diff;
			maxMap.y += diff;
		}
		if (minScreen.x < minMap.x) offset.x += minMap.x - minScreen.x;
		if (maxScreen.x > maxMap.x) offset.x -= maxScreen.x - maxMap.x;
		if (minScreen.y < minMap.y) offset.y += minMap.y - minScreen.y;
		if (maxScreen.y > maxMap.y) offset.y -= maxScreen.y - maxMap.y;
		return offset;
	}