Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Pinch zoom and touch pan on a navigation map

Discussion in '2D' started by LucasJSR, Jun 17, 2023.

  1. LucasJSR

    LucasJSR

    Joined:
    Aug 15, 2020
    Posts:
    13
    Hello everyone,

    So I have a 2D navigation map (a 2D image with the sprite of a map as the source image) in my mobile app, and I want to let the user pinch zoom the map and pan the map (when zoomed in) with touch. The 2D map image was placed as a child of a canvas, and a second camera (called "NavMap Camera") is used to render the map's canvas over the main camera.

    I added a "box collider 2D" component to the 2D map image so it could detect the user's touch, and a "NavMap" tag was added both to the 2D map image itself and its parent canvas (in order to detect if the user is doing the pinch zoom directly on the 2D map). I wrote the following script for the zoom/pan functionalities:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ZoomNavMap : MonoBehaviour
    6. {
    7.  
    8.     const float ZOOM_MIN = 1f;
    9.     const float ZOOM_MAX = 5f;
    10.  
    11.     const float PAN_Y_DIST = 3f;
    12.     const float PAN_X_DIST = 4f;
    13.  
    14.     public Camera cameraNavMap;
    15.  
    16.     Vector3 initCameraPos;
    17.  
    18.     Touch touch;
    19.  
    20.     bool isZoomed;
    21.  
    22.     Vector3 touchPan;
    23.  
    24.     // Start is called before the first frame update
    25.     void Start()
    26.     {
    27.  
    28.         initCameraPos = cameraNavMap.transform.position;
    29.  
    30.     }
    31.  
    32.     // Update is called once per frame
    33.     void Update()
    34.     {
    35.  
    36.         Zoom();
    37.         ZoomPan();
    38.  
    39.     }
    40.  
    41.     void Zoom()
    42.     {
    43.  
    44.         if (Input.touchCount == 2)
    45.         {
    46.  
    47.             Touch touchZero = Input.GetTouch(0);
    48.             Touch touchOne = Input.GetTouch(1);
    49.  
    50.             Vector2 touchZeroUltPos = touchZero.position - touchZero.deltaPosition;
    51.             Vector2 touchOneUltPos = touchOne.position - touchOne.deltaPosition;
    52.  
    53.             float lastMag = (touchZeroLastPos - touchOneLastPos).magnitude;
    54.             float currentMag = (touchZero.position - touchOne.position).magnitude;
    55.  
    56.             float magDif = currentMag - lastMag;
    57.  
    58.             float incr = magDif * 0.01f;
    59.  
    60.             Ray raycastZero = cameraNavMap.ScreenPointToRay(Input.GetTouch(0).position);
    61.             RaycastHit raycastZeroHit;
    62.  
    63.             if (Physics.Raycast(raycastZero, out raycastZeroHit))
    64.             {
    65.  
    66.                 if (raycastZeroHit.collider.CompareTag("NavMap"))
    67.                 {
    68.  
    69.                     Debug.Log("Tag: " + raycastZeroHit.collider.tag);
    70.  
    71.                     cameraNavMap.orthographicSize = Mathf.Clamp((cameraNavMap.orthographicSize - incr), ZOOM_MIN, ZOOM_MAX);
    72.  
    73.                 }
    74.  
    75.             }
    76.  
    77.         }
    78.  
    79.  
    80.         if (cameraNavMap.orthographicSize < 4.49f)
    81.         {
    82.  
    83.             isZoomed = true;
    84.  
    85.         }
    86.  
    87.         else
    88.         {
    89.  
    90.             isZoomed = false;
    91.  
    92.             cameraNavMap.transform.position = initCameraPos;
    93.  
    94.         }
    95.  
    96.     }
    97.  
    98.     void ZoomPan()
    99.     {
    100.  
    101.         if (isZoomed == true)
    102.         {
    103.  
    104.             if (Input.touchCount == 1)
    105.             {
    106.  
    107.                 touch = Input.GetTouch(0);
    108.  
    109.                 if (touch.phase == TouchPhase.Began)
    110.                 {
    111.  
    112.                     touchPan = cameraNavMap.ScreenToWorldPoint(touch.position);
    113.  
    114.                 }
    115.  
    116.                 if (touch.phase == TouchPhase.Moved)
    117.                 {
    118.  
    119.                     Ray raycast = cameraNavMap.ScreenPointToRay(Input.GetTouch(0).position);
    120.  
    121.                     RaycastHit raycastHit;
    122.  
    123.  
    124.                     if (Physics.Raycast(raycast, out raycastHit))
    125.                     {
    126.  
    127.                         //Debug.Log("Tag: " + raycastHit.collider.tag);
    128.  
    129.                         if (raycastHit.collider.CompareTag("NavMap"))
    130.                         {
    131.  
    132.                             Vector3 direction = touchPan - cameraNavMap.ScreenToWorldPoint(touch.position);
    133.  
    134.                             cameraNavMap.transform.position = new Vector3(Mathf.Clamp((cameraNavMap.transform.position.x + direction.x), -PAN_X_DIST, PAN_X_DIST), Mathf.Clamp((cameraNavMap.transform.position.y + direction.y), -PAN_Y_DIST, PAN_Y_DIST / 2f));
    135.  
    136.                         }
    137.  
    138.                     }
    139.  
    140.                 }
    141.  
    142.             }
    143.  
    144.         }
    145.  
    146.     }
    147.  
    148. }
    149.  
    However, nothing is happening. I even included some "Debug.Log" lines to check if the touch on the map was being correctly detected, but it seems like it's not.

    I really don't know what I'm doing wrong, so if someone could help me out with this, I would be really thankful.
     
  2. karderos

    karderos

    Joined:
    Mar 28, 2023
    Posts:
    376
    well if your debug log isnt showing it means the raycast is not being successful you should start from there

    do you have a collider in the map, etc
     
    LucasJSR likes this.
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    If you're using 2D physics then you should be using the 2D physics API not the 3D physics API.

    Also, you don't use a raycast to check in the Z direction in 2D because there isn't a Z direction, it's 2D! You'd use Physics2D.OverlapPoint.

    Given the above, it seems you've not gone through any 2D physics tutorials and are jumping straight into code so I would highly recommend doing some learning tutorials first.
     
    LucasJSR likes this.
  4. LucasJSR

    LucasJSR

    Joined:
    Aug 15, 2020
    Posts:
    13
    Yes you're right, I started with a 3D project and I stupidly thought that I could just copy/paste the zoom code to the 2D project and it would work LOL

    I'll read some 2D tutorials then, thanks for the help!
     
    MelvMay likes this.