Search Unity

Mobile touch to Orbit pan and zoom Camera, without fix target in one script

Discussion in 'Scripting' started by Stromerz, Mar 19, 2018.

  1. Stromerz

    Stromerz

    Joined:
    Jan 25, 2018
    Posts:
    13
    Hello guys,
    Um very new in UNITY, last couple of days I was trying to make a camera in unity which will behave just like sketchfab camera.


    I found some example which works with mouse movement perfectly. But I need to make it works in Mobile as well, Since um very new in unity I couldn't figure out how to rewrite the code to make it works with touch, can anyone help me with this, Thanks in Advance

    Code (CSharp):
    1. Using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. [AddComponentMenu("Camera-Control/3dsMax Camera Style")]
    5. public class maxCamera : MonoBehaviour
    6. {
    7.      public Transform target;
    8.      public Vector3 targetOffset;
    9.      public float distance = 5.0f;
    10.      public float maxDistance = 20;
    11.      public float minDistance = .6f;
    12.      public float xSpeed = 200.0f;
    13.      public float ySpeed = 200.0f;
    14.      public int yMinLimit = -80;
    15.      public int yMaxLimit = 80;
    16.      public int zoomRate = 40;
    17.      public float panSpeed = 0.3f;
    18.      public float zoomDampening = 5.0f;
    19.      private float xDeg = 0.0f;
    20.      private float yDeg = 0.0f;
    21.      private float currentDistance;
    22.      private float desiredDistance;
    23.      private Quaternion currentRotation;
    24.      private Quaternion desiredRotation;
    25.      private Quaternion rotation;
    26.      private Vector3 position;
    27.      void Start() { Init(); }
    28.      void OnEnable() { Init(); }
    29.      public void Init()
    30.      {
    31.          //If there is no target, create a temporary target at 'distance' from the cameras current viewpoint
    32.          if (!target)
    33.          {
    34.              GameObject go = new GameObject("Cam Target");
    35.              go.transform.position = transform.position + (transform.forward * distance);
    36.              target = go.transform;
    37.          }
    38.          distance = Vector3.Distance(transform.position, target.position);
    39.          currentDistance = distance;
    40.          desiredDistance = distance;
    41.          //be sure to grab the current rotations as starting points.
    42.          position = transform.position;
    43.          rotation = transform.rotation;
    44.          currentRotation = transform.rotation;
    45.          desiredRotation = transform.rotation;
    46.          xDeg = Vector3.Angle(Vector3.right, transform.right);
    47.          yDeg = Vector3.Angle(Vector3.up, transform.up);
    48.      }
    49.      /*
    50.       * Camera logic on LateUpdate to only update after all character movement logic has been handled.
    51.       */
    52.      void LateUpdate()
    53.      {
    54.          // If Control and Alt and Middle button? ZOOM!
    55.          if (Input.GetMouseButton(2))
    56.          {
    57.              desiredDistance -= Input.GetAxis("Mouse Y") * Time.deltaTime * zoomRate * 0.125f * Mathf.Abs(desiredDistance);
    58.          }
    59.          // If middle mouse and left alt are selected? ORBIT
    60.          if (Input.GetMouseButton(0))
    61.          {
    62.              xDeg += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
    63.              yDeg -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
    64.              ////////OrbitAngle
    65.              //Clamp the vertical axis for the orbit
    66.              yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
    67.              // set camera rotation
    68.              desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
    69.              currentRotation = transform.rotation;
    70.              rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
    71.              transform.rotation = rotation;
    72.          }
    73.          // otherwise if middle mouse is selected, we pan by way of transforming the target in screenspace
    74.          else if (Input.GetMouseButton(2))
    75.          {
    76.              //grab the rotation of the camera so we can move in a psuedo local XY space
    77.              target.rotation = transform.rotation;
    78.              target.Translate(Vector3.right * -Input.GetAxis("Mouse X") * panSpeed);
    79.              target.Translate(transform.up * -Input.GetAxis("Mouse Y") * panSpeed, Space.World);
    80.          }
    81.          ////////Orbit Position
    82.          // affect the desired Zoom distance if we roll the scrollwheel
    83.          desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
    84.          //clamp the zoom min/max
    85.          desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
    86.          // For smoothing of the zoom, lerp distance
    87.          currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening);
    88.          // calculate position based on the new currentDistance
    89.          position = target.position - (rotation * Vector3.forward * currentDistance + targetOffset);
    90.          transform.position = position;
    91.      }
    92.      private static float ClampAngle(float angle, float min, float max)
    93.      {
    94.          if (angle < -360)
    95.              angle += 360;
    96.          if (angle > 360)
    97.              angle -= 360;
    98.          return Mathf.Clamp(angle, min, max);
    99.      }
    100. }
     
    SwiftSkillz and Emotical like this.
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
  3. Stromerz

    Stromerz

    Joined:
    Jan 25, 2018
    Posts:
    13
    thanks for replay Grozzler, can you please help me rewrite this code
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    What have you tried? What part of your changes aren't working?
     
  5. Stromerz

    Stromerz

    Joined:
    Jan 25, 2018
    Posts:
    13
    um using this code for camera pan and zoom, which works perfect for now


    // variables for camera pan
    public float speedPan;

    // variables for camera zoom in and out
    public float perspectiveZoomSpeed;
    public float orthoZoomSpeed;
    public Camera mainCamera;

    //variables for camera orbit
    public Vector3 FirstPoint;
    public Vector3 SecondPoint;
    public float xAngle; //angle for axes x for rotation
    public float yAngle;
    public float xAngleTemp; //temp variable for angle
    public float yAngleTemp;

    // Use this for initialization
    void Start ()
    {

    }

    // Update is called once per frame
    void Update ()
    {

    // This part is for camera pan only & for 2 fingers stationary gesture
    if (Input.touchCount>0 && Input.GetTouch(1).phase == TouchPhase.Moved)
    {

    Vector2 touchDeltaPosition = Input.GetTouch (0).deltaPosition;
    transform.Translate (-touchDeltaPosition.x * speedPan, -touchDeltaPosition.y * speedPan, 0);
    }


    //this part is for zoom in and out
    if (Input.touchCount == 2)
    {
    Touch touchZero = Input.GetTouch (0);
    Touch touchOne = Input.GetTouch (1);

    Vector2 touchZeroPreviousPosition = touchZero.position - touchZero.deltaPosition;
    Vector2 touchOnePreviousPosition = touchOne.position - touchOne.deltaPosition;

    float prevTouchDeltaMag = (touchZeroPreviousPosition - touchOnePreviousPosition).magnitude;
    float TouchDeltaMag = (touchZero.position - touchOne.position).magnitude;

    float deltaMagDiff = prevTouchDeltaMag - TouchDeltaMag;


    if (mainCamera.orthographic)
    {
    mainCamera.orthographicSize += deltaMagDiff * orthoZoomSpeed;
    mainCamera.orthographicSize = Mathf.Max (mainCamera.orthographicSize, .1f);
    } else
    {
    mainCamera.fieldOfView += deltaMagDiff * perspectiveZoomSpeed;
    mainCamera.fieldOfView = Mathf.Clamp (mainCamera.fieldOfView, .1f, 179.9f);
    }

    }

    }
    }

    [ICODE]
     
    twicejiggled and ABB13 like this.
  6. Stromerz

    Stromerz

    Joined:
    Jan 25, 2018
    Posts:
    13
    um using this code for rotate, which is not what i want

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class cameraRotate : MonoBehaviour {

    //Exp 2
    public Transform target;
    public float distance = 10.0f;
    public float xSpeed = 60.0f;
    public float ySpeed = 60.0f;
    public float yMinLimit = 10f;
    public float yMaxLimit = 60f;
    public float distanceMin = 5f;
    public float distanceMax = 10f;
    float x = 0.0f;
    float y = 0.0f;


    void Start()
    {
    Vector3 angles = transform.eulerAngles;
    float x = angles.y;
    float y = angles.x;
    // Make the rigid body not change rotation
    if (GetComponent<Rigidbody>())
    GetComponent<Rigidbody>().freezeRotation = true;
    }

    void LateUpdate()
    {
    if (target && Input.touchCount == 1 && Input.GetTouch(0).position.x > Screen.width / 2 && Input.GetTouch(0).phase == TouchPhase.Moved) //Just orbit touch without movement
    {
    Debug.Log("Orbiting! 1 touch");
    Orbit(Input.GetTouch(0));
    }
    else if (Input.touchCount == 2)
    {
    if (Input.GetTouch(0).position.x > Screen.width / 2 && Input.GetTouch(0).phase == TouchPhase.Moved)
    Orbit(Input.GetTouch(0)); //Movement was touched second
    else if (Input.GetTouch(1).position.x > Screen.width / 2 && Input.GetTouch(1).phase == TouchPhase.Moved)
    Orbit(Input.GetTouch(1)); //Movement was touched first
    }
    }

    void Orbit(Touch touch)
    {
    x += touch.deltaPosition.x * xSpeed * 0.02f /* * distance*/;
    y -= touch.deltaPosition.y * ySpeed * 0.02f /* * distance*/;
    y = ClampAngle(y, yMinLimit, yMaxLimit);
    Quaternion rotation = Quaternion.Euler(y, x, 0);
    //distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
    RaycastHit hit;
    if (Physics.Linecast(target.position, transform.position, out hit))
    {
    // distance -= hit.distance;
    }
    Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
    Vector3 position = rotation * negDistance + target.position;
    transform.rotation = rotation;
    transform.position = position;
    }

    public static float ClampAngle(float angle, float min, float max)
    {
    if (angle < -360F)
    angle += 360F;
    if (angle > 360F)
    angle -= 360F;
    return Mathf.Clamp(angle, min, max);

    }
    }
     
  7. Stromerz

    Stromerz

    Joined:
    Jan 25, 2018
    Posts:
    13
    I want my camera to orbit around an object but the user can change the target position by panning the camera with using 2 finger move,
    whatever the target is camera always rotate around that target position using 1 finger move
    & whatever the target is camera zoom with pinching
     
  8. Stromerz

    Stromerz

    Joined:
    Jan 25, 2018
    Posts:
    13
    right now the code um using for orbit around the object won't let me change the target while um panning with 2 fingers, also the distance is always remaining the same
     
  9. Liyou1085066875

    Liyou1085066875

    Joined:
    May 20, 2016
    Posts:
    1
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class MobilemaxCamera : MonoBehaviour {
    7.  
    8.     public Transform target;
    9.     public Vector3 targetOffset;
    10.     public float distance = 5.0f;
    11.     public float maxDistance = 20;
    12.     public float minDistance = .6f;
    13.     public float xSpeed = 5.0f;
    14.     public float ySpeed = 5.0f;
    15.     public int yMinLimit = -80;
    16.     public int yMaxLimit = 80;
    17.     public float zoomRate = 10.0f;
    18.     public float panSpeed = 0.3f;
    19.     public float zoomDampening = 5.0f;
    20.  
    21.     private float xDeg = 0.0f;
    22.     private float yDeg = 0.0f;
    23.     private float currentDistance;
    24.     private float desiredDistance;
    25.     private Quaternion currentRotation;
    26.     private Quaternion desiredRotation;
    27.     private Quaternion rotation;
    28.     private Vector3 position;
    29.  
    30.     private Vector3 FirstPosition;
    31.     private Vector3 SecondPosition;
    32.     private Vector3 delta;
    33.     private Vector3 lastOffset;
    34.     private Vector3 lastOffsettemp;
    35.     //private Vector3 CameraPosition;
    36.     //private Vector3 Targetposition;
    37.     //private Vector3 MoveDistance;
    38.  
    39.  
    40.     void Start() { Init(); }
    41.     void OnEnable() { Init(); }
    42.  
    43.     public void Init()
    44.     {
    45.         //If there is no target, create a temporary target at 'distance' from the cameras current viewpoint
    46.         if (!target)
    47.         {
    48.             GameObject go = new GameObject("Cam Target");
    49.             go.transform.position = transform.position + (transform.forward * distance);
    50.             target = go.transform;
    51.         }
    52.  
    53.         distance = Vector3.Distance(transform.position, target.position);
    54.         currentDistance = distance;
    55.         desiredDistance = distance;
    56.  
    57.         //be sure to grab the current rotations as starting points.
    58.         position = transform.position;
    59.         rotation = transform.rotation;
    60.         currentRotation = transform.rotation;
    61.         desiredRotation = transform.rotation;
    62.  
    63.         xDeg = Vector3.Angle(Vector3.right, transform.right);
    64.         yDeg = Vector3.Angle(Vector3.up, transform.up);
    65.     }
    66.  
    67.     /*
    68.       * Camera logic on LateUpdate to only update after all character movement logic has been handled.
    69.       */
    70.     void LateUpdate()
    71.     {
    72.         // If Control and Alt and Middle button? ZOOM!
    73.         if (Input.touchCount==2)
    74.         {
    75.             Touch touchZero = Input.GetTouch (0);
    76.  
    77.             Touch touchOne = Input.GetTouch (1);
    78.  
    79.  
    80.  
    81.             Vector2 touchZeroPreviousPosition = touchZero.position - touchZero.deltaPosition;
    82.  
    83.             Vector2 touchOnePreviousPosition = touchOne.position - touchOne.deltaPosition;
    84.  
    85.  
    86.  
    87.             float prevTouchDeltaMag = (touchZeroPreviousPosition - touchOnePreviousPosition).magnitude;
    88.  
    89.             float TouchDeltaMag = (touchZero.position - touchOne.position).magnitude;
    90.  
    91.  
    92.  
    93.             float deltaMagDiff = prevTouchDeltaMag - TouchDeltaMag;
    94.  
    95.             desiredDistance += deltaMagDiff * Time.deltaTime * zoomRate * 0.0025f * Mathf.Abs(desiredDistance);
    96.         }
    97.         // If middle mouse and left alt are selected? ORBIT
    98.         if (Input.touchCount==1 && Input.GetTouch(0).phase == TouchPhase.Moved)
    99.         {
    100.             Vector2 touchposition = Input.GetTouch(0).deltaPosition;
    101.             xDeg += touchposition.x * xSpeed * 0.002f;
    102.             yDeg -= touchposition.y * ySpeed * 0.002f;
    103.             yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
    104.  
    105.         }
    106.         desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
    107.         currentRotation = transform.rotation;
    108.         rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
    109.         transform.rotation = rotation;
    110.  
    111.  
    112.         if (Input.GetMouseButtonDown (1))
    113.         {
    114.             FirstPosition = Input.mousePosition;
    115.             lastOffset = targetOffset;
    116.         }
    117.  
    118.         if (Input.GetMouseButton (1))
    119.         {
    120.             SecondPosition = Input.mousePosition;
    121.             delta = SecondPosition - FirstPosition;
    122.             targetOffset = lastOffset + transform.right * delta.x*0.003f + transform.up * delta.y*0.003f;
    123.  
    124.         }
    125.  
    126.         ////////Orbit Position
    127.  
    128.         // affect the desired Zoom distance if we roll the scrollwheel
    129.         desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
    130.         currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening);
    131.  
    132.         position = target.position - (rotation * Vector3.forward * currentDistance );
    133.  
    134.         position = position - targetOffset;
    135.  
    136.         transform.position = position;
    137.  
    138.  
    139.  
    140.  
    141.     }
    142.     private static float ClampAngle(float angle, float min, float max)
    143.     {
    144.         if (angle < -360)
    145.             angle += 360;
    146.         if (angle > 360)
    147.             angle -= 360;
    148.         return Mathf.Clamp(angle, min, max);
    149.     }
    150. }
    151.  
    hope this can help you!
     
    Last edited: Jun 14, 2018
    Sancejas, mmtukur, Jwako and 22 others like this.
  10. SamohtVII

    SamohtVII

    Joined:
    Jun 30, 2014
    Posts:
    370
    Dude that code is amazing. Thank you so much!
     
  11. shinip2

    shinip2

    Joined:
    May 1, 2019
    Posts:
    1
    Appreciate your help! Thx
     
  12. hosamre94

    hosamre94

    Joined:
    Jan 18, 2017
    Posts:
    2
     
    hadinaufal and Amosbaker like this.
  13. florinel2102

    florinel2102

    Joined:
    May 21, 2019
    Posts:
    76
    Liyou1085066875 you saved my night :) . Thanks a lot !
     
  14. nikko2000

    nikko2000

    Joined:
    Dec 11, 2015
    Posts:
    1
    I have to agree that's excellent Liyou
     
  15. chaitanyajadhav

    chaitanyajadhav

    Joined:
    Nov 23, 2019
    Posts:
    1
    That's really great Liyou Appreciate your help. It saved lot of time for me.
     
  16. campbal

    campbal

    Joined:
    Oct 19, 2015
    Posts:
    3
    First, thank you for this great code!
    One question: For me, the pan speed is extremely slow and only moves a very small distance. I've tried adjusting the "Pan Speed" variable (up to 10000+), but the pan speed stays the same. I've tried looking through he code to see where I could tweak values, but I can't determine how to do this (limited coding skills). Also, I'm using this on a tablet PC, so not sure if that might be causing the issue since nobody else in this thread has commented on having a problem like this. Any thoughts on what might be the cause?

    Again, thank you so much for the code - it's been a life saver!
     
  17. campbal

    campbal

    Joined:
    Oct 19, 2015
    Posts:
    3
    Figured it out: The values in the code below were set at .003. I changed to .1 and now it works perfectly :)
    The code is at line 112 if you just copied and pasted Liyou's original code.

    Code (CSharp):
    1.         if (Input.GetMouseButton(1)) {
    2.             SecondPosition = Input.mousePosition;
    3.             delta = SecondPosition - FirstPosition;
    4.             targetOffset = lastOffset + transform.right * delta.x * 0.1f + transform.up * delta.y * 0.1f;
    5.  
    6.         }
    7.  
    8.         ////////Orbit Position
     
  18. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    488
    Hi I am facing a problem in Liyou's code. I have initial position and rotation set to camera before the play mode. But when I click on play, it completely changes its transforms. How do I stop this from happening?
     
    NationPranav likes this.
  19. Straniero

    Straniero

    Joined:
    Oct 15, 2019
    Posts:
    1
    Unfortunately i have the same issue... :(
     
  20. Leinion

    Leinion

    Joined:
    Mar 27, 2017
    Posts:
    2
    at public void Init(), change the xDeg and yDeg
    Code (CSharp):
    1. xDeg = transform.eulerAngles.y + Vector3.Angle(Vector3.right, transform.right);
    2. yDeg = transform.eulerAngles.x + Vector3.Angle(Vector3.up, transform.up);
    hope this help
     
  21. hcpinteractive

    hcpinteractive

    Joined:
    May 20, 2019
    Posts:
    9
    This does not work for me. First let me thank to Liyou for the super smooth script. But as other mentioned it has this position rotation shifting issue. At start and especially in my case where I am trying to reposition and reorient camera to fixed locations on button click. It locates around somewhere near to position and rotation I pass but never fits to exact location. Also some time it lerps a bit. I am trying to fix this since days but not being able to find a fix. How to fix this? Something must be done to this position = target.position - (rotation * Vector3.forward * currentDistance); but can't find.
     
  22. xGunsxLordx

    xGunsxLordx

    Joined:
    Apr 5, 2020
    Posts:
    1
    Can i use this code in unity 3d?
    i want to rotate around my object only in one axis around its pivot, second thing i want to do is to pinch and zoom on that object but with limit so that it will not zoom in or out much (basically i have done these 2 things already). and the third thing i want to do is to pan (just pan thing is remaining is you can help me with it).
     
  23. Jwako

    Jwako

    Joined:
    May 22, 2019
    Posts:
    8
    Here's a version liyous code updated for the new InputSystem, with panning fixed.
    Some of the default variables have the camera moving and rotating really slow, so remember to try increasing those if it seems the camera isn't moving like it should.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6. using UnityEngine.InputSystem.Controls;
    7. using UnityEngine.InputSystem.EnhancedTouch;
    8.  
    9. public class CameraMovement : MonoBehaviour
    10. {
    11.  
    12.     public Transform target;
    13.     public Vector3 targetOffset;
    14.     public float distance = 5.0f;
    15.     public float maxDistance = 20;
    16.     public float minDistance = .6f;
    17.     public float xSpeed = 5.0f;
    18.     public float ySpeed = 5.0f;
    19.     public int yMinLimit = -80;
    20.     public int yMaxLimit = 80;
    21.     public float zoomRate = 10.0f;
    22.     public float panSpeed = 0.3f;
    23.     public float zoomDampening = 5.0f;
    24.  
    25.     private float xDeg = 0.0f;
    26.     private float yDeg = 0.0f;
    27.     private float currentDistance;
    28.     private float desiredDistance;
    29.     private Quaternion currentRotation;
    30.     private Quaternion desiredRotation;
    31.     private Quaternion rotation;
    32.     private Vector3 position;
    33.  
    34.     private Vector3 FirstPosition;
    35.     private Vector3 SecondPosition;
    36.     private Vector3 delta;
    37.     private Vector3 lastOffset;
    38.     private Vector3 lastOffsettemp;
    39.     //private Vector3 CameraPosition;
    40.     //private Vector3 Targetposition;
    41.     //private Vector3 MoveDistance;
    42.  
    43.     private Touchscreen screen;
    44.  
    45.  
    46.     void Start() { Init(); }
    47.     void OnEnable() { Init(); }
    48.  
    49.     public void Init()
    50.     {
    51.         //If there is no target, create a temporary target at 'distance' from the cameras current viewpoint
    52.         if (!target)
    53.         {
    54.             GameObject go = new GameObject("Cam Target");
    55.             go.transform.position = transform.position + (transform.forward * distance);
    56.             target = go.transform;
    57.         }
    58.  
    59.         distance = Vector3.Distance(transform.position, target.position);
    60.         currentDistance = distance;
    61.         desiredDistance = distance;
    62.  
    63.         //be sure to grab the current rotations as starting points.
    64.         position = transform.position;
    65.         rotation = transform.rotation;
    66.         currentRotation = transform.rotation;
    67.         desiredRotation = transform.rotation;
    68.  
    69.         xDeg = Vector3.Angle(Vector3.right, transform.right);
    70.         yDeg = Vector3.Angle(Vector3.up, transform.up);
    71.  
    72.         Debug.Log("CAMERA MOVEMENT INIT SUCCESS\nTOUCHSCREEN INPUT FOUND: " + (Touchscreen.current != null).ToString().ToUpper());
    73.         screen = Touchscreen.current;
    74.     }
    75.  
    76.     /*
    77.       * Camera logic on LateUpdate to only update after all character movement logic has been handled.
    78.       */
    79.     void LateUpdate()
    80.     {
    81.         if (!Application.isEditor)
    82.         {
    83.             List<TouchControl> touches = ActiveTouches(screen);
    84.             Debug.Log("touches: " + touches.Count.ToString());
    85.  
    86.             //ZOOM & PAN
    87.             if (touches.Count == 2)
    88.             {
    89.                 Debug.Log("CAM_MOVE Two Touches");
    90.                 TouchControl touchZero = touches[0];
    91.  
    92.                 TouchControl touchOne = touches[1];
    93.  
    94.  
    95.                 //ZOOM
    96.                 Vector2 touchZeroPreviousPosition = touchZero.position.ReadValue() - touchZero.delta.ReadValue();
    97.  
    98.                 Vector2 touchOnePreviousPosition = touchOne.position.ReadValue() - touchOne.delta.ReadValue();
    99.  
    100.  
    101.                 float prevTouchDeltaMag = (touchZeroPreviousPosition - touchOnePreviousPosition).magnitude;
    102.  
    103.                 float TouchDeltaMag = (touchZero.position.ReadValue() - touchOne.position.ReadValue()).magnitude;
    104.  
    105.  
    106.                 float deltaMagDiff = prevTouchDeltaMag - TouchDeltaMag;
    107.  
    108.                 desiredDistance += deltaMagDiff * Time.deltaTime * zoomRate * 0.0025f * Mathf.Abs(desiredDistance);
    109.  
    110.                 //PAN
    111.                 //store previous center position of touches
    112.                 Vector2 previousPositionMiddle = (touchZeroPreviousPosition + touchOnePreviousPosition) / 2;
    113.  
    114.                 //store current center position of touches
    115.                 Vector2 currentPositionMiddle = (touchZero.position.ReadValue() + touchOne.position.ReadValue()) / 2;
    116.  
    117.                 //store delta of previous two
    118.                 Vector2 middlePositionDelta = currentPositionMiddle - previousPositionMiddle;
    119.  
    120.  
    121.                 lastOffset = targetOffset;
    122.                 //set a multiplier for de facto pan speed based on zoom level
    123.                 float speedMulti = 0.003f * panSpeed * currentDistance;
    124.                 //move targetoffset on the XZ plane according to the delta
    125.                 targetOffset = lastOffset + transform.right * middlePositionDelta.x * speedMulti + Quaternion.Euler(0, -90, 0) * transform.right * middlePositionDelta.y * speedMulti;
    126.             }
    127.             //ORBIT
    128.             if (touches.Count == 1 && touches[0].phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Moved)
    129.             {
    130.                 Debug.Log("CAM_MOVE Moving Single Touch");
    131.                 Vector2 touchposition = touches[0].delta.ReadValue();
    132.                 xDeg += touchposition.x * xSpeed * 0.002f;
    133.                 yDeg -= touchposition.y * ySpeed * 0.002f;
    134.                 yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
    135.             }
    136.         }
    137.         desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
    138.         currentRotation = transform.rotation;
    139.         rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
    140.         transform.rotation = rotation;
    141.  
    142.         /*
    143.         if (Mouse.current.leftButton.isPressed)
    144.         {
    145.             FirstPosition = Mouse.current.position.ReadValue();
    146.             lastOffset = targetOffset;
    147.         }
    148.  
    149.         if (Mouse.current.rightButton.isPressed)
    150.         {
    151.             SecondPosition = Mouse.current.position.ReadValue();
    152.             delta = SecondPosition - FirstPosition;
    153.             targetOffset = lastOffset + transform.right * delta.x * 0.003f + transform.up * delta.y * 0.003f;
    154.  
    155.         }
    156.         */
    157.  
    158.         ////////Orbit Position
    159.  
    160.         // affect the desired Zoom distance if we roll the scrollwheel
    161.         desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
    162.         currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening);
    163.  
    164.         position = target.position - (rotation * Vector3.forward * currentDistance);
    165.  
    166.         position = position - targetOffset;
    167.  
    168.         transform.position = position;
    169.     }
    170.     private static float ClampAngle(float angle, float min, float max)
    171.     {
    172.         if (angle < -360)
    173.             angle += 360;
    174.         if (angle > 360)
    175.             angle -= 360;
    176.         return Mathf.Clamp(angle, min, max);
    177.     }
    178.  
    179.     private List<TouchControl> ActiveTouches(Touchscreen screen)
    180.     {
    181.         List<TouchControl> i = new List<TouchControl>();
    182.         foreach (var item in screen.touches)
    183.         {
    184.             if (item.isInProgress)
    185.                 i.Add(item);
    186.         }
    187.         return i;
    188.     }
    189. }
    190.  
     
    Last edited: May 11, 2022
    mmtukur likes this.
  24. sagarbalas

    sagarbalas

    Joined:
    Jul 9, 2019
    Posts:
    1
    Shows,
    The type or namespace name 'InputSystem' does not exist in the namespace 'UnityEngine' (are you missing an assembly reference?)

    can you please help
     
  25. Jwako

    Jwako

    Joined:
    May 22, 2019
    Posts:
    8
    Sounds like you don't have the new InputSystem package installed, if its something else i really don't know.
     
    marcosssdsd likes this.
  26. hadinaufal

    hadinaufal

    Joined:
    May 12, 2022
    Posts:
    2
    how can i make the camera keep center to the object ?
     
  27. Jwako

    Jwako

    Joined:
    May 22, 2019
    Posts:
    8
    Set the object as the target and set pan speed to 0. That should have the camera follow the object and be able to zoom and rotate around it, but not allow the user to move the target. If you want to swap the target at runtime, this might still work but i haven't tested it
     
  28. hadinaufal

    hadinaufal

    Joined:
    May 12, 2022
    Posts:
    2
    it work thanks
     
  29. Ally80s

    Ally80s

    Joined:
    Mar 23, 2022
    Posts:
    1
    Thanks for this thread :)
    Just wondering, how could you apply this code to a unity game to allow a trackpad to control touches? Rather than a touchscreen.


     
  30. NickJainschigg

    NickJainschigg

    Joined:
    Mar 11, 2013
    Posts:
    16
    Liyou's mobile code here is EXACTLY what I've been looking for to learn from! If you're still around, Liyou, thank you a thousand times!
    Now I just need to figure out how to port it to the new input system. Not looking for help on that, as it's my bear to cross, but this is such a great learning example that I'm feeling really optimistic for the first time in weeks!
     
  31. Jwako

    Jwako

    Joined:
    May 22, 2019
    Posts:
    8
    Unity doesn't support multitouch input natively so you'd probably have to figure some special out for that. I think at the very least you'd have to generalize the script to use pointer data instead of the touch interface.
    There are some trackpad support plugins in the store, but the ones i found either are made for using the trackpad in the editor, or haven't been updated for the new InputSystem.
     
    Ally80s likes this.
  32. Nikeneo

    Nikeneo

    Joined:
    Jan 23, 2021
    Posts:
    2
    I have revised the basic script of Liyou. It now automatically recognizes the control (old input system) whether PC (right mouse) or mobile (touch), and the mode can also be set to move or rotate.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public enum CameraMode {
    4.     Move,
    5.     Rotate
    6. }
    7. public class CameraController : MonoBehaviour {
    8.     public CameraMode Mode = CameraMode.Move;
    9.     public Transform target;
    10.     public Vector3 targetOffset;
    11.     public float distance = 5.0f;
    12.     public float maxDistance = 20;
    13.     public float minDistance = .6f;
    14.     public float xSpeed = 5.0f;
    15.     public float ySpeed = 5.0f;
    16.     public int yMinLimit = -80;
    17.     public int yMaxLimit = 80;
    18.     public float zoomRate = 10.0f;
    19.     public float panSpeed = 0.3f;
    20.     public float zoomDampening = 5.0f;
    21.  
    22.     private float xDeg = 0.0f;
    23.     private float yDeg = 0.0f;
    24.     private float currentDistance;
    25.     private float desiredDistance;
    26.     private Quaternion currentRotation;
    27.     private Quaternion desiredRotation;
    28.     private Quaternion rotation;
    29.     private Vector3 position;
    30.  
    31.     private Vector3 FirstPosition;
    32.     private Vector3 SecondPosition;
    33.     private Vector3 delta;
    34.     private Vector3 lastOffset;
    35.     private Vector3 lastOffsettemp;
    36.     //private Vector3 CameraPosition;
    37.     //private Vector3 Targetposition;
    38.     //private Vector3 MoveDistance;
    39.  
    40.  
    41.     void Start() { Init(); }
    42.     void OnEnable() { Init(); }
    43.  
    44.     public void Init() {
    45.         if (!target) {
    46.             GameObject go = new GameObject("Cam Target");
    47.             go.transform.position = transform.position + (transform.forward * distance);
    48.             target = go.transform;
    49.         }
    50.  
    51.         distance = Vector3.Distance(transform.position, target.position);
    52.         currentDistance = distance;
    53.         desiredDistance = distance;
    54.        
    55.         position = transform.position;
    56.         rotation = transform.rotation;
    57.         currentRotation = transform.rotation;
    58.         desiredRotation = transform.rotation;
    59.  
    60.         xDeg = Vector3.Angle(Vector3.right, transform.right);
    61.         yDeg = Vector3.Angle(Vector3.up, transform.up);
    62.     }
    63.    
    64.     void LateUpdate() {
    65.         HandleInput();
    66.         Rotate();
    67.         Move();
    68.     }
    69.  
    70.     private void Move() {
    71.         desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
    72.         currentDistance = Mathf.Lerp(currentDistance, desiredDistance, Time.deltaTime * zoomDampening);
    73.         position = target.position - (rotation * Vector3.forward * currentDistance );
    74.         position = position - targetOffset;
    75.         transform.position = position;
    76.     }
    77.  
    78.     private void Rotate() {
    79.         desiredRotation = Quaternion.Euler(yDeg, xDeg, 0);
    80.         currentRotation = transform.rotation;
    81.         rotation = Quaternion.Lerp(currentRotation, desiredRotation, Time.deltaTime * zoomDampening);
    82.         transform.rotation = rotation;
    83.     }
    84.  
    85.     private void HandleInput() {
    86.         if (SystemInfo.deviceType == DeviceType.Desktop) {
    87.             if (Input.GetMouseButtonDown (1)) {
    88.                 FirstPosition = Input.mousePosition;
    89.                 lastOffset = targetOffset;
    90.             }
    91.  
    92.             if (Input.GetMouseButton (1)) {
    93.                 SecondPosition = Input.mousePosition;
    94.                 delta = SecondPosition - FirstPosition;
    95.  
    96.                 if (Mode == CameraMode.Rotate) {
    97.                     if (delta.magnitude > .1) {
    98.                         xDeg += delta.x * xSpeed/2 * 0.002f;
    99.                         yDeg -= delta.y * ySpeed/2 * 0.002f;
    100.                         yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
    101.                     }
    102.                 }
    103.                 else if(Mode == CameraMode.Move) {
    104.                     targetOffset = lastOffset + transform.right * delta.x * 0.003f + transform.up * delta.y * 0.003f;
    105.                 }
    106.             }
    107.         } else if (SystemInfo.deviceType == DeviceType.Handheld) {
    108.             if (Input.touchCount == 2) { // Zoom
    109.                 Touch touchZero = Input.GetTouch (0);
    110.                 Touch touchOne = Input.GetTouch (1);
    111.            
    112.                 Vector2 touchZeroPreviousPosition = touchZero.position - touchZero.deltaPosition;
    113.                 Vector2 touchOnePreviousPosition = touchOne.position - touchOne.deltaPosition;
    114.            
    115.                 float prevTouchDeltaMag = (touchZeroPreviousPosition - touchOnePreviousPosition).magnitude;
    116.                 float TouchDeltaMag = (touchZero.position - touchOne.position).magnitude;
    117.                 float deltaMagDiff = prevTouchDeltaMag - TouchDeltaMag;
    118.  
    119.                 desiredDistance += deltaMagDiff * Time.deltaTime * zoomRate * 0.0025f * Mathf.Abs(desiredDistance);
    120.             }
    121.            
    122.             if (Mode == CameraMode.Rotate) {
    123.                 if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved) { // Orbit
    124.                     Vector2 touchposition = Input.GetTouch(0).deltaPosition;
    125.                     xDeg += touchposition.x * xSpeed * 0.002f;
    126.                     yDeg -= touchposition.y * ySpeed * 0.002f;
    127.                     yDeg = ClampAngle(yDeg, yMinLimit, yMaxLimit);
    128.                 }
    129.             }
    130.             else if(Mode == CameraMode.Move) {
    131.                 if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved) {
    132.                     lastOffset = targetOffset;
    133.                     Vector2 touchposition = Input.GetTouch(0).deltaPosition;
    134.                     targetOffset = lastOffset + transform.right * touchposition.x * 0.003f + transform.up * touchposition.y * 0.003f;
    135.                 }
    136.             }
    137.            
    138.         }
    139.     }
    140.  
    141.     private static float ClampAngle(float angle, float min, float max)
    142.     {
    143.         if (angle < -360)
    144.             angle += 360;
    145.         if (angle > 360)
    146.             angle -= 360;
    147.         return Mathf.Clamp(angle, min, max);
    148.     }
    149. }
    150.