Part of these game systems:
Pinch-to-Zoom Camera
Smooth pinch-to-zoom camera control for mobile devices supporting both orthographic and perspective cameras. Features configurable zoom limits and optional smoothing.
How to Use
1
Attach the PinchToZoomCamera script to your Main Camera
2
Set minZoom and maxZoom limits in the inspector
3
Enable autoDetectMode to automatically configure for orthographic or perspective
4
Adjust zoomSpeed and smoothSpeed to taste
5
Test with two-finger pinch on a mobile device or use Remote in the editor
Source Code
C#
using UnityEngine;
public class PinchToZoomCamera : MonoBehaviour
{
[Header("Zoom Settings")]
[SerializeField] private float zoomSpeed = 0.5f;
[SerializeField] private float minZoom = 2f;
[SerializeField] private float maxZoom = 20f;
[Header("Smoothing")]
[SerializeField] private bool enableSmoothing = true;
[SerializeField] private float smoothSpeed = 8f;
[Header("Camera Mode")]
[SerializeField] private bool autoDetectMode = true;
private Camera cam;
private float targetZoom;
private float previousTouchDistance;
private bool isPinching;
private void Awake()
{
cam = GetComponent<Camera>();
if (cam == null)
cam = Camera.main;
if (autoDetectMode)
{
minZoom = cam.orthographic ? 1f : 20f;
maxZoom = cam.orthographic ? 30f : 100f;
}
targetZoom = cam.orthographic ? cam.orthographicSize : cam.fieldOfView;
}
private void Update()
{
HandlePinchInput();
ApplyZoom();
}
private void HandlePinchInput()
{
if (Input.touchCount == 2)
{
Touch touch0 = Input.GetTouch(0);
Touch touch1 = Input.GetTouch(1);
float currentDistance = Vector2.Distance(touch0.position, touch1.position);
if (!isPinching)
{
isPinching = true;
previousTouchDistance = currentDistance;
return;
}
float delta = previousTouchDistance - currentDistance;
float zoomDelta = delta * zoomSpeed * Time.deltaTime;
targetZoom += zoomDelta;
targetZoom = Mathf.Clamp(targetZoom, minZoom, maxZoom);
previousTouchDistance = currentDistance;
}
else
{
isPinching = false;
}
// Mouse scroll fallback for editor testing
float scroll = Input.GetAxis("Mouse ScrollWheel");
if (Mathf.Abs(scroll) > 0.01f)
{
targetZoom -= scroll * zoomSpeed * 100f * Time.deltaTime;
targetZoom = Mathf.Clamp(targetZoom, minZoom, maxZoom);
}
}
private void ApplyZoom()
{
if (cam.orthographic)
{
if (enableSmoothing)
cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, targetZoom, Time.deltaTime * smoothSpeed);
else
cam.orthographicSize = targetZoom;
}
else
{
if (enableSmoothing)
cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, targetZoom, Time.deltaTime * smoothSpeed);
else
cam.fieldOfView = targetZoom;
}
}
public void SetZoom(float zoom)
{
targetZoom = Mathf.Clamp(zoom, minZoom, maxZoom);
}
public void ResetZoom()
{
targetZoom = cam.orthographic ? 5f : 60f;
}
public float GetCurrentZoom()
{
return cam.orthographic ? cam.orthographicSize : cam.fieldOfView;
}
public float GetZoomNormalized()
{
float current = GetCurrentZoom();
return Mathf.InverseLerp(minZoom, maxZoom, current);
}
}