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;
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 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;
}
}