Zoom with two fingers initial position

I am trying to use zoom with two fingers but unfortunately whenever I place two fingers together, the starting value of camera.fieldOfView changes drastically. I feel it goes to some other value. It should start from the current value. What am I doing wrong here?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.EnhancedTouch;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;

public Camera camera;

    float touchDist = 0;
    float lastDist = 0;
    public float maxAngle = 60;
    public float minAngle = 30;

    private void Start()
    {
        EnhancedTouchSupport.Enable();
    }
    public void Update()
    {

        if (Touch.activeFingers.Count == 2)
        {
            Touch activeTouch = Touch.activeFingers[0].currentTouch;

            Touch touch1 = Touch.activeFingers[0].currentTouch;
            Touch touch2 = Touch.activeFingers[1].currentTouch;

            if (touch1.phase == UnityEngine.InputSystem.TouchPhase.Began && touch2.phase == UnityEngine.InputSystem.TouchPhase.Began)
            {
                lastDist = Vector2.Distance(touch1.screenPosition, touch2.screenPosition);
            }

            if (touch1.phase == UnityEngine.InputSystem.TouchPhase.Moved && touch2.phase == UnityEngine.InputSystem.TouchPhase.Moved)
            {
                float newDist = Vector2.Distance(touch1.screenPosition, touch2.screenPosition);
                touchDist = lastDist - newDist;
                lastDist = newDist;

                // Your Code Here
                camera.fieldOfView += touchDist * 0.05f;

                if (camera.fieldOfView > maxAngle)
                {
                    camera.fieldOfView = maxAngle;
                }

                if (camera.fieldOfView < minAngle)
                {
                    camera.fieldOfView = minAngle;
                }

            }
        }

    }

}

You’re never gonna get those two fingers to start at the same instant in time (or at least rarely).

Instead, note the transition from NOT having 2 fingers down to the point where you DO have 2 fingers down.

That’s the frame you want to record the initial distance from which you compute deltas beyond that.

I wouldn’t even pay attention to the touchphases. They don’t really help you.

Something simple like this:

if (touchcount == 2)
{
  // get touches as above

  float distance = (compute here from touches)

// record reference finger distance only at the moment
//  you have 2 fingers and you didn't the frame before
  if (prevtouchCount != 2)
  {
    firstDistance = distance;
    originalZoom = Camera.FOV;
  }

  // now take the ratio of current distance to firstDistance and
  // adjust zoom from originalZoom
  float ratio = distance / firstDistance;

  currentZoom = originalZoom / ratio;

// probably want to clamp this
  currentZoom = Mathf.Clamp( currentZoom, 5, 70);

  Camera.FOV = currentZoom;
}

// for comparing next frame
prevtouchCount = touchcount;

Hi,

Thank you for taking your time to explain the logic. I used your logic to implement in my code in this manner. And it worked! Glad you helped :slight_smile: Just one question, is there a way to control the speed of the zoom?
@Kurt-Dekker

    public Camera camera;
    int prevtouchCount;
    float firstDistance;
    float originalZoom;
    float currentZoom;
  
void Update(){
if (Touch.activeFingers.Count == 2) {
          // get touches as above

          Touch touch1 = Touch.activeFingers[0].currentTouch;
          Touch touch2 = Touch.activeFingers[1].currentTouch;

          float distance = Vector2.Distance(touch1.screenPosition, touch2.screenPosition);

          // record reference finger distance only at the moment
          //  you have 2 fingers and you didn't the frame before
          if (prevtouchCount != 2) {
            firstDistance = distance;
            originalZoom = camera.fieldOfView;
          }

          // now take the ratio of current distance to firstDistance and
          // adjust zoom from originalZoom
          float ratio = distance / firstDistance;

          currentZoom = originalZoom / ratio;

          // probably want to clamp this
          currentZoom = Mathf.Clamp(currentZoom, 5, 70);

          camera.fieldOfView = currentZoom;
        }

        // for comparing next frame
        prevtouchCount = Touch.activeFingers.Count;

        }
}

I think you want to limit how far away ratio gets from 1.0…

so maybe this right after you calculate ratio above:

// after you calculate ratio...
ratio -= 1.0f;
ratio /= 10;   // dampen it a LOT!
ratio += 1.0f;
// now go on to use ratio
1 Like