- Home /
Touch code for panning and zooming not working
I'm using Unity 2017 and working in 2D with an orthographic camera.
The problem is I can't wrap my head arround whats wrong with my code.
I just want to pan and zoom the camera with touch and only do this when not over an UI element but nothing is working.
If you could help me or point me out where I made a mistake, I would be so thankful.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class CameraController : MonoBehaviour {
Vector2 StartPosition;
Vector2 DragStartPosition;
Vector2 DragNewPosition;
Vector2 Finger0Position;
float DistanceBetweenFingers;
public float zoomOutMin = 6;
public float zoomOutMax = 20;
void Update () {
checkTouchOnScreen ();
}
void checkTouchOnScreen () {
if (Input.touchCount > 0 && Input.GetTouch(0).phase ==TouchPhase.Began) {
//Make sure finger is NOT over a UI element
if (!EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) {
OnScreenTouched ();
}
}
}
void OnScreenTouched () {
Debug.Log ("not over UI");
if (Input.touchCount == 1) {
if (Input.GetTouch(0).phase == TouchPhase.Moved) {
Vector2 NewPosition = GetWorldPosition();
Vector2 PositionDifference = NewPosition - StartPosition;
Camera.main.transform.Translate (-PositionDifference);
}
StartPosition = GetWorldPosition ();
} else if (Input.touchCount == 2) {
if (Input.GetTouch(1).phase == TouchPhase.Moved) {
DragNewPosition = GetWorldPositionOfFinger(1);
Vector2 PositionDifference = DragNewPosition - DragStartPosition;
if (Vector2.Distance (DragNewPosition, Finger0Position) < DistanceBetweenFingers) {
Camera.main.orthographicSize += (PositionDifference.magnitude);
}
if (Vector2.Distance (DragNewPosition, Finger0Position) >= DistanceBetweenFingers) {
Camera.main.orthographicSize -= (PositionDifference.magnitude);
}
DistanceBetweenFingers = Vector2.Distance (DragNewPosition, Finger0Position);
}
DragStartPosition = GetWorldPositionOfFinger (1);
Finger0Position = GetWorldPositionOfFinger (0);
}
}
Vector2 GetWorldPosition () {
return Camera.main.ScreenToWorldPoint (Input.mousePosition);
}
Vector2 GetWorldPositionOfFinger (int FingerIndex) {
return Camera.main.ScreenToWorldPoint (Input.GetTouch (FingerIndex).position);
}
}
Answer by Leycarno · Feb 14, 2019 at 07:35 AM
Your code works just for the moment the touch starts. So you get the first position but no changes.
void checkTouchOnScreen () {
if (Input.touchCount > 0 && Input.GetTouch(0).phase ==TouchPhase.Began) {
Handle the "TouchPhase.Began" together with the other ones:
Thank you for your answer.
So I've read the docs but, I'm not sure if I understand you right with "Handle the "TouchPhase.Began" together with the other ones".
How would I do this exactly with my current code?
Should I use a switch statement?
EDIT :
At the moment I can't try it, but do you mean something like this :
Can't post this code to my other reply, sorry.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class CameraController : $$anonymous$$onoBehaviour {
Vector2 StartPosition;
Vector2 DragStartPosition;
Vector2 DragNewPosition;
Vector2 Finger0Position;
float DistanceBetweenFingers;
bool isZoo$$anonymous$$g;
public float zoomOut$$anonymous$$in = 6;
public float zoomOut$$anonymous$$ax = 20;
void Update () {
checkTouchOnScreen ();
}
void checkTouchOnScreen () {
if (Input.touchCount > 0) {
//$$anonymous$$ake sure finger is NOT over a UI element
if (!EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) {
OnScreenTouched ();
}
}
}
void OnScreenTouched () {
Debug.Log ("not over UI");
if (Input.touchCount == 1 && !isZoo$$anonymous$$g) {
Touch touch = Input.GetTouch (0);
switch (touch.phase) {
case TouchPhase.Began:
StartPosition = GetWorldPosition ();
break;
case TouchPhase.$$anonymous$$oved:
Vector2 NewPosition = GetWorldPosition(); // EDIT "NewPosition"
Vector2 PositionDifference = NewPosition - StartPosition;
Camera.main.transform.Translate (-PositionDifference);
break;
case TouchPhase.Ended:
break;
}
} else if (Input.touchCount == 2) {
Touch touch = Input.GetTouch (1);
isZoo$$anonymous$$g = true;
switch (touch.phase) {
case TouchPhase.Began:
DragStartPosition = GetWorldPositionOfFinger (1);
Finger0Position = GetWorldPositionOfFinger (0);
break;
case TouchPhase.$$anonymous$$oved:
DragNewPosition = GetWorldPositionOfFinger(1);
Vector2 PositionDifference = DragNewPosition - DragStartPosition;
if (Vector2.Distance (DragNewPosition, Finger0Position) < DistanceBetweenFingers) {
Camera.main.orthographicSize += (PositionDifference.magnitude);
}
if (Vector2.Distance (DragNewPosition, Finger0Position) >= DistanceBetweenFingers) {
Camera.main.orthographicSize -= (PositionDifference.magnitude);
}
DistanceBetweenFingers = Vector2.Distance (DragNewPosition, Finger0Position);
break;
case TouchPhase.Ended:
isZoo$$anonymous$$g = false;
break;
}
}
}
Vector2 GetWorldPosition () {
return Camera.main.ScreenToWorldPoint (Input.mousePosition);
}
Vector2 GetWorldPositionOfFinger (int FingerIndex) {
return Camera.main.ScreenToWorldPoint (Input.GetTouch (FingerIndex).position);
}
}
That's what I meant. Sorry for the delay - I can look deeper into the code after work...
No problem at all, glad you are helping me with my problem.
is this the complete code? Where did "NewPosition" come from?
Oh maybe i deleted it. Sorry.
In the original question i get the "NewPosition".
And no it is not the complete code just the snippets for the panning amd zoo$$anonymous$$g. The other code is for getting the target when it moves.
EDIT : added the snippet fot the "NewPosition" in the reply
So it's untested, but maybe it helps:
using UnityEngine;
using UnityEngine.EventSystems;
public class CameraController : $$anonymous$$onoBehaviour {
Vector2 _lastPosition;
Vector2 _dragStartPosition;
Vector2 _dragNewPosition;
Vector2 _finger0Position;
float _distanceBetweenFingers;
public float _zoomOut$$anonymous$$in = 6;
public float _zoomOut$$anonymous$$ax = 20;
Camera _mainCam;
void Start() {
_mainCam = Camera.main;
}
void Update() {
CheckTouchOnScreen();
}
void CheckTouchOnScreen() {
if (Input.touchCount <= 0) return;
//$$anonymous$$ake sure finger is NOT over a UI element
if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)) return;
Debug.Log("not over UI");
switch (Input.touchCount) {
case 1:
PanCam();
break;
case 2:
ZoomCam();
break;
// TODO: what about > 2 touches?
}
}
void PanCam() {
if (Input.GetTouch(0).phase == TouchPhase.$$anonymous$$oved) {
var newPosition = GetWorldPosition();
var positionDifference = newPosition - _lastPosition;
_mainCam.transform.Translate(-positionDifference);
}
_lastPosition = GetWorldPosition();
}
void ZoomCam() {
_dragNewPosition = GetWorldPositionOfFinger(1);
if (Input.GetTouch(1).phase == TouchPhase.$$anonymous$$oved) {
var positionDifference = _dragNewPosition - _dragStartPosition;
if (Vector2.Distance(_dragNewPosition, _finger0Position) < _distanceBetweenFingers) {
_mainCam.orthographicSize += (positionDifference.magnitude);
}
if (Vector2.Distance(_dragNewPosition, _finger0Position) >= _distanceBetweenFingers) {
_mainCam.orthographicSize -= (positionDifference.magnitude);
}
_distanceBetweenFingers = Vector2.Distance(_dragNewPosition, _finger0Position);
}
_dragStartPosition = _dragNewPosition;
_finger0Position = GetWorldPositionOfFinger(0);
}
Vector2 GetWorldPosition() {
return _mainCam.ScreenToWorldPoint(Input.mousePosition);
}
Vector2 GetWorldPositionOfFinger(int fingerIndex) {
return _mainCam.ScreenToWorldPoint(Input.GetTouch(fingerIndex).position);
}
}
Thank you so much, I will try it when I'm at home. But looks promising to me.
But why return if touchCount > 0 ?
void CheckTouchOnScreen() {
if (Input.touchCount > 0) return;
When I'm at home I'll let you know how it works.
So i thought about the zoo$$anonymous$$g function and wrote my own script for it now it all works like a charm, thank you so much for helping me. ;D
Your answer
Follow this Question
Related Questions
How do you differentiate between pinch to zoom with two fingers and a two finger drag? 2 Answers
Angry birds style zoom effect 1 Answer
Modified Mobile TapControl.js logic flow works, but No Apparent Cam Zoom/Rotate Response 1 Answer
How to centre a 3D pinch zoom 1 Answer
Zooming in and out with an orthographic camera, while the bottom edge is fixed. 0 Answers