title: Zooming limit in unity mobile. Perspective Camera
body: <p>I'm trying to limit the zoom value of my game to a minimum and a maximum but i can't get how to do it!
  I've been trying by limiting the Y according to the zoom factor but it does not work properly, because when it reaches the limit, it starts flickering, like it hit an obstacle. I found some things that can solve this problem by using the fieldofview, but I need it to work with the Y limitations!
  I also want to add a panning limit, so that the player won't be able to see the end of the map but I didn't get there yet.</p>
  
  <p>Anyways, here is the code i'm using and would appreciate if someone could help!</p>
  
  <pre><code>using UnityEngine;
  using System.Collections;
  using System.Collections.Generic;
  
  class ScrollAndPinch : MonoBehaviour
  {
  #if UNITY_IOS || UNITY_ANDROID
    public Camera Camera;
    public bool Rotate;
    protected Plane Plane;
  
    public float scrollSpeed;
    public float rotateSpeed;
    public float zoomSpeed;
  
    public float zoomMinY;
    public float zoomMaxY;
  
    public float camsummer;
  
    Vector3 pos;
    private Vector3 velocity = Vector3.zero;
  
  
    private void Awake()
    {
      if (Camera == null)
        Camera = Camera.main;
  
      Rotate = true;
  
      scrollSpeed = 50f;
      rotateSpeed = 50f;
      zoomSpeed = 1f;
  
      zoomMinY = 50f;
      zoomMaxY = 200f;
  
      camsummer = 0.1f;
  
      pos = new Vector3(0f, 0f, 0f);
  
    }
  
    private void Update()
    {
  
      //Update Plane
      if (Input.touchCount &gt;= 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 * scrollSpeed * Time.deltaTime, 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 to be done relative to the distance moved between the fingers
        var zoom = (Vector3.Distance(pos1, pos2) /
                   Vector3.Distance(pos1b, pos2b));
  
        //edge case (Bad calculation)
        if (zoom == 0 || zoom &gt; 10)
          return;
  
        //Move cam amount the mid ray. This is where the zoom is applied
  
        // Vector3 pos = Camera.transform.position;
        // pos.y = Mathf.Clamp(pos.y, zoomMinY, zoomMaxY);
        // Camera.transform.position = Vector3.Lerp(pos1, Camera.transform.position, (1 / zoom));
        // Camera.transform.position = pos;
  
  
  
        if (Camera.transform.position.y &lt; zoomMinY | Camera.transform.position.y &gt; zoomMaxY)
        {
          // Camera.transform.position = pos;
          Camera.transform.position = Vector3.SmoothDamp(Camera.transform.position, pos, ref velocity, camsummer);
          // Camera.transform.position = Vector3.LerpUnclamped(Camera.transform.position, pos, camsummer);
          // for (int i = 0; i &lt; 1000; i++)
          // {
          // }
  
        }
        else if (Camera.transform.position.y &gt;= zoomMinY &amp;&amp; Camera.transform.position.y &lt;= zoomMaxY)
        {
          pos = Camera.transform.position;
          Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
          //This is where the rotation is applied
          if (Rotate &amp;&amp; pos2b != pos2)
            Camera.transform.RotateAround(pos1, Plane.normal,
              Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Plane.normal) * rotateSpeed * Time.deltaTime);
        }
        // pos.y = zoomMinY;
      }
  
  
  
      // if (Camera.transform.position.y &gt; 200)
      // {
      //   zoomMaxY.y = 200;
      //   Camera.transform.position = zoomMaxY;
      // }
      // else if (Camera.transform.position.y &lt; 50)
      // {
      //   zoomMinY.y = 50;
      //   Camera.transform.position = zoomMinY;
      // }
      // else if (Camera.transform.position.y &gt;= 50 &amp;&amp; Camera.transform.position.y &lt;= 200)
      // {
      //   Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
      // }
  
  
      // Vector3 Cam = Mathf.Clamp(Camera.transform.position.y, zoomMinY.y, zoomMaxY.y);
  
  
      // if (Camera.transform.position.y &gt; zoomMaxY || Camera.transform.position.y &lt; zoomMinY)
      // {
      //   Vector3 camLimit = Camera.transform.position;
      //   camLimit.y = Mathf.Clamp(Camera.transform.position.y, zoomMinY, zoomMaxY);
      //   Camera.transform.position = camLimit;
  
  
  
      //   // Vector3 camLimit = Camera.transform.position;
      //   // camLimit = (transform.position.);
      //   // Camera.transform.position = camLimit;
      // }
      // else if (Camera.transform.position.y &gt;= zoomMinY &amp;&amp; Camera.transform.position.y &lt;= zoomMaxY)
      // {
      //   Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
      // }
  
  
  
  
  
    }
  
    protected Vector3 PlanePositionDelta(Touch touch)
    {
      //not moved
      if (touch.phase != TouchPhase.Moved)
        return Vector3.zero;
  
      //delta: How far have we moved from A to B by sliding the finger
      var rayBefore = Camera.ScreenPointToRay(touch.position - touch.deltaPosition);
      var rayNow = Camera.ScreenPointToRay(touch.position);
      if (Plane.Raycast(rayBefore, out var enterBefore) &amp;&amp; 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
  }
  </code></pre>
  
  <p>And to make it easier to see, this is the part I am struggling to make it work.</p>
  
  <pre><code>if (Camera.transform.position.y &lt; zoomMinY | Camera.transform.position.y &gt; zoomMaxY)
        {
          Camera.transform.position = Vector3.SmoothDamp(Camera.transform.position, pos, ref velocity, camsummer);
  
  
        }
        else if (Camera.transform.position.y &gt;= zoomMinY &amp;&amp; Camera.transform.position.y &lt;= zoomMaxY)
        {
          pos = Camera.transform.position;
          Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
          //This is where the rotation is applied
          if (Rotate &amp;&amp; pos2b != pos2)
            Camera.transform.RotateAround(pos1, Plane.normal,
              Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Plane.normal) * rotateSpeed * Time.deltaTime);
        }
  </code></pre>