Skip to content

Instantly share code, notes, and snippets.

@ditzel
Created July 22, 2019 17:12
Show Gist options
  • Save ditzel/836bb36d7f70e2aec2dd87ebe1ede432 to your computer and use it in GitHub Desktop.
Save ditzel/836bb36d7f70e2aec2dd87ebe1ede432 to your computer and use it in GitHub Desktop.
Pinch and Scroll to Move and Zoom in Unity for Mobile Games
/*
Set this on an empty game object positioned at (0,0,0) and attach your active camera.
The script only runs on mobile devices or the remote app.
*/
using UnityEngine;
class ScrollAndPinch : MonoBehaviour
{
#if UNITY_IOS || UNITY_ANDROID
public Camera Camera;
public bool Rotate;
protected Plane Plane;
private void Awake()
{
if (Camera == null)
Camera = Camera.main;
}
private void Update()
{
//Update Plane
if (Input.touchCount >= 1)
Plane.SetNormalAndPosition(transform.up, transform.position);
var Delta1 = Vector3.zero;
var Delta2 = Vector3.zero;
//Scroll
if (Input.touchCount >= 1)
{
Delta1 = PlanePositionDelta(Input.GetTouch(0));
if (Input.GetTouch(0).phase == TouchPhase.Moved)
Camera.transform.Translate(Delta1, Space.World);
}
//Pinch
if (Input.touchCount >= 2)
{
var pos1 = PlanePosition(Input.GetTouch(0).position);
var pos2 = PlanePosition(Input.GetTouch(1).position);
var pos1b = PlanePosition(Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition);
var pos2b = PlanePosition(Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition);
//calc zoom
var zoom = Vector3.Distance(pos1, pos2) /
Vector3.Distance(pos1b, pos2b);
//edge case
if (zoom == 0 || zoom > 10)
return;
//Move cam amount the mid ray
Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, 1 / zoom);
if (Rotate && pos2b != pos2)
Camera.transform.RotateAround(pos1, Plane.normal, Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Plane.normal));
}
}
protected Vector3 PlanePositionDelta(Touch touch)
{
//not moved
if (touch.phase != TouchPhase.Moved)
return Vector3.zero;
//delta
var rayBefore = Camera.ScreenPointToRay(touch.position - touch.deltaPosition);
var rayNow = Camera.ScreenPointToRay(touch.position);
if (Plane.Raycast(rayBefore, out var enterBefore) && Plane.Raycast(rayNow, out var enterNow))
return rayBefore.GetPoint(enterBefore) - rayNow.GetPoint(enterNow);
//not on plane
return Vector3.zero;
}
protected Vector3 PlanePosition(Vector2 screenPos)
{
//position
var rayNow = Camera.ScreenPointToRay(screenPos);
if (Plane.Raycast(rayNow, out var enterNow))
return rayNow.GetPoint(enterNow);
return Vector3.zero;
}
private void OnDrawGizmos()
{
Gizmos.DrawLine(transform.position, transform.position + transform.up);
}
#endif
}
@manildayma
Copy link

I noticed that the pinch and scroll take away the camera to out of bounds. This glitch makes the map out sight by totally zooming in or zooming out by the user, hence creating a situation to restart the app. If there is an add-on to prevent moving the camera out of specific area then it would have been a great script. The scroll and pinch features works well, though.

@ditzel
Copy link
Author

ditzel commented Aug 12, 2020

After the //scroll section you can add a few lines to keep the camera in your bounds.

@VishwakanthDanaboina
Copy link

After the //scroll section you can add a few lines to keep the camera in your bounds.

Can you please tell me what lines of code needs to be set to keep the camera in the bounds.

@AndreiPrystupchyk
Copy link

Can you help dont understand why not working

NullReferenceException: Object reference not set to an instance of an object
CameraControl.PlanePositionDelta (UnityEngine.Touch touch) (at Assets/CameraControl.cs:67)
CameraControl.Update () (at Assets/CameraControl.cs:30)

@Karam000
Copy link

Can you help dont understand why not working

NullReferenceException: Object reference not set to an instance of an object
CameraControl.PlanePositionDelta (UnityEngine.Touch touch) (at Assets/CameraControl.cs:67)
CameraControl.Update () (at Assets/CameraControl.cs:30)

Have you referenced the camera and plane from the inspector ?

@Kudoshi
Copy link

Kudoshi commented Mar 24, 2021

To anyone who wants to:

  • Restrict the zoom in and out of the camera
  • Adjust camera pan speed

Check out the fork that i made. I have added a few simple lines of code to do the above function.

@dzak83
Copy link

dzak83 commented Dec 19, 2021

Thanks for sharing this script @ditzel, it's very useful and helped me today a lot :) 🙏

You should know that someone out there is thinking good things about you today and wish you well! :D

@djavadihamid
Copy link

@ditzel you are the best
@Kudoshi thanks for the great fork!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment