Search Unity

Rotation gesture

Discussion in 'iOS and tvOS' started by ej2009, Apr 28, 2011.

  1. ej2009

    ej2009

    Joined:
    Mar 2, 2009
    Posts:
    353
    Hi,

    does anyone have or know where to find rotation gesture script?

    I don't need to rotate and object etc, just to detect that rotation gesture was performed (I need this for tile rotation inside game editor).

    Thanks in advance!
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    You can use code like the following to recognise the typical two-finger rotation gesture:-
    Code (csharp):
    1. var rotating: boolean;
    2. var startVector: Vector2;
    3. var rotGestureWidth: float;
    4. var rotAngleMinimum: float;
    5.  
    6. function Update () {
    7.     if (Input.touchCount == 2) {
    8.         if (!rotating) {
    9.             startVector = Input.GetTouch(1).position - Input.GetTouch(0).position;
    10.             rotating = startVector.sqrMagnitude > rotGestureWidth * rotGestureWidth;
    11.         } else {
    12.             var currVector = Input.GetTouch(1).position - Input.GetTouch(0).position;
    13.             var angleOffset = Vector2.Angle(startVector, currVector);
    14.             var LR = Vector3.Cross(startVector, currVector);
    15.            
    16.             if (angleOffset > rotAngleMinimum) {
    17.                 if (LR.z > 0) {
    18.                     // Anticlockwise turn equal to angleOffset.
    19.                 } else if (LR.z < 0) {
    20.                     // Clockwise turn equal to angleOffset.
    21.                 }
    22.             }
    23.            
    24.         }
    25.        
    26.     } else {
    27.         rotating = false;
    28.     }
    29. }
    The rotGestureWidth is used to specify the minimum distance between the fingers for the gesture to be recognised as a rotation, which could be useful if you need to use other two-finger gestures. The rotAngleMinimum value is the minimum angle that the fingers must be rotated before the gesture is accepted. Without knowing exactly what you are doing, it is difficult to be more specific than this but the code should give you a start at least.
     
    florinel2102, mkusan and ZenithCode like this.
  3. ej2009

    ej2009

    Joined:
    Mar 2, 2009
    Posts:
    353
    Thanks a lot mate, this is what I was looking for, perfect!
     
  4. gringofxs

    gringofxs

    Joined:
    Oct 14, 2012
    Posts:
    240
    I use the script, on a C# but unity gives an error, (error CS8025: Parsing error) how can i fix?

     
  5. vinay_vidhani

    vinay_vidhani

    Joined:
    Oct 27, 2016
    Posts:
    10
    @Andee's code is awesome, I just made a minor change to make his code more robust,

    Ok So what was the problem I faced that is when I am moving my both fingers, and when I was changing the direction then after may be 1 second the next direction was updating (If I am rotating left then after 1 second my object was rotating to right) and another which is bigger, that was If I am putting one finger let say at 12 o'clock and another finger pointing to 6 o' clock then also the result was incorrect so that I made those changes to make It perfect..


    bool rotating;
    Vector2 startVector;
    float rotGestureWidth;
    float rotAngleMinimum;

    public Text sampleText;

    private void Update () {
    if (Input.touchCount == 2) {
    if (!rotating) {
    startVector = Input.GetTouch(1).position - Input.GetTouch(0).position;
    rotating = startVector.sqrMagnitude > rotGestureWidth * rotGestureWidth;
    } else {
    var currVector = Input.GetTouch(1).position - Input.GetTouch(0).position;
    var angleOffset = Vector2.Angle(startVector, currVector);
    var LR = Vector3.Cross(startVector, currVector);

    if (angleOffset > rotAngleMinimum) {
    if (LR.z > 0) {
    sampleText.text = "rotate left";
    startVector= currVector;
    } else if (LR.z < 0) {
    sampleText.text = "rotate right";
    startVector= currVector;
    }
    }

    }

    } else {
    rotating = false;
    }
    }
     
  6. Overnaut

    Overnaut

    Joined:
    Aug 25, 2017
    Posts:
    19
    Tanks for the code. Here an updated, improved, more readable, commented version with changes for my game.
    Code (CSharp):
    1.     /// Flag set to true if the user currently makes an rotation gesture, otherwise false
    2.     private bool rotating = false;
    3.     /// The squared rotation width determining an rotation
    4.     public const float TOUCH_ROTATION_WIDTH = 1; // Always
    5.     /// The threshold in angles which must be exceeded so a touch rotation is recogniced as one
    6.     public const float TOUCH_ROTATION_MINIMUM = 1;
    7.     /// Start vector of the current rotation
    8.     Vector2 startVector = Vector2.zero;
    9.  
    10.     /// Processes input for touch rotation, only the first two touches are used
    11.     private void TouchRotation (){
    12.         if (Input.touchCount == 2) {
    13.             if (!rotating) {
    14.                 startVector = Input.touches [1].position - Input.touches [0].position;
    15.                 rotating = startVector.sqrMagnitude > TOUCH_ROTATION_WIDTH;
    16.             } else {
    17.                 Vector2 currVector = Input.touches [1].position - Input.touches [0].position;
    18.                 float angleOffset = Vector2.Angle(startVector, currVector);
    19.  
    20.                 if (angleOffset > TOUCH_ROTATION_MINIMUM) {
    21.                     Vector3 LR = Vector3.Cross(startVector, currVector); // z > 0 left rotation, z < 0 right rotation
    22.  
    23.                     if(LR.z > 0)
    24.                         mouseLook.y += angleOffset;
    25.                     else if(LR.z < 0)
    26.                         mouseLook.y -= angleOffset;
    27.                  
    28.                     mouseLook.y = Mathf.Clamp (mouseLook.y, 0, 180F); // Clamp looking down and up
    29.  
    30.                     GameController.Instance.mainCamera.transform.localRotation = Quaternion.AngleAxis (-mouseLook.y, Vector3.right);
    31.                     startVector = currVector;
    32.                 }
    33.             }
    34.         } else
    35.             rotating = false;
    36.     }
     
  7. florinel2102

    florinel2102

    Joined:
    May 21, 2019
    Posts:
    76
    I think it's more simpler to use Vector2.SignedAngle method so it will not be necessary to use Vector3.Cross , just verify Mathf.Abs(Vector2.SignedAngle) > rotAngleMinimum , also a good value for rotAngleMinimum is in [4.5 , 8] .
     
  8. BernEugen

    BernEugen

    Joined:
    Mar 13, 2015
    Posts:
    4
    Hi, could be even simpler:
    Code (CSharp):
    1. private void Update()
    2. {
    3.   if (Input.touchCount == 2)
    4.   {
    5.     var touchOne = Input.GetTouch(0);
    6.     var touchTwo = Input.GetTouch(1);
    7.  
    8.     if (touchOne.phase == TouchPhase.Began
    9.         || touchTwo.phase == TouchPhase.Began)
    10.     {
    11.         _startPosition = touchTwo.position - touchOne.position;
    12.     }
    13.  
    14.     if (touchOne.phase == TouchPhase.Moved
    15.         || touchTwo.phase == TouchPhase.Moved)
    16.     {
    17.         var currVector = touchTwo.position - touchOne.position;
    18.         var angle = Vector2.SignedAngle(_startPosition, currVector);
    19.         _target.transform.rotation = Quaternion.Euler(0.0f, _target.transform.rotation.eulerAngles.y + angle, 0.0f);
    20.         _startPosition = currVector;
    21.     }
    22.   }
    23. }
     
    LT23Live likes this.
  9. LT23Live

    LT23Live

    Joined:
    Jul 8, 2014
    Posts:
    97
    This is like cheat codes in GTA. Thank you very much! This worked wonders.