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

Detecting a Circle 'swipe gesture' on touch screen.

Discussion in 'Scripting' started by lucax, Mar 30, 2014.

  1. lucax

    lucax

    Joined:
    Jul 2, 2010
    Posts:
    12
    Hey guys, I think its my first post here. Well coming to point, I want to ask how could I implement a circular swipe gesture?

    Further info : Just like how you swipe in temple run when you move your finger left it turns left, I want to be able to do something when player makes a circle or say semicircle on screen with finger (swiping it in circular form).

    More Info and Original Script for Swipe(left/right/up) : (To Unity Answers) http://answers.unity3d.com/questions/673672/swipe-control-for-circle-can-do-swipe-leftright.html
     
  2. lucax

    lucax

    Joined:
    Jul 2, 2010
    Posts:
    12
    Anyone ? (bump)
     
  3. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    Well, how far have you got? What have you tried? What approaches have you thought about?
     
  4. lucax

    lucax

    Joined:
    Jul 2, 2010
    Posts:
    12
    That is the point I have no idea how this can be accomplished.
    I have tried putting fp.x = lp.x as a condition in the TouchPhase.Moved (Referring to the script linked in OP).
    But that doesn't seems to work. I am not asking you to code it for me, just a way to implement this in my script.
     
  5. Bivrost

    Bivrost

    Joined:
    Mar 26, 2014
    Posts:
    80
  6. Graham-Dunnett

    Graham-Dunnett

    Unity Technologies

    Joined:
    Jun 2, 2009
    Posts:
    4,287
    This is some code I had sitting around. It's not an answer to how you detect a circle gesture, but might get you moving in the direction you need. If I was solving this problem today I think I'd use something like https://depts.washington.edu/aimgroup/proj/dollar/index.html.

    Code (csharp):
    1.  
    2. //cs example
    3. //capture touch events and draw vectors connecting them
    4. //assume touch define a circle, so measure variation in radius and compute centre
    5. using UnityEngine;
    6. using System.Collections;
    7. using System.Collections.Generic;
    8.  
    9. public class lines : MonoBehaviour {
    10.  
    11.     private static readonly Color lineColor  = new Color (1f, 0f, 0f, 0.88f);
    12.     private static readonly Color lineColorLight  = new Color (1f, 0f, 0f, 0.28f);
    13.     private static bool done = false;
    14.     private static Vector2 vCenter;
    15.     private static Vector2 vRadius;
    16.     private static float fAngle;
    17.    
    18.     List<Vector2> lineList;
    19.    
    20.     // Use this for initialization
    21.     void Start ()
    22.     {
    23.         CreateLineMaterial();
    24.         lineList = new List<Vector2>();
    25.     }
    26.  
    27.     void Update()
    28.     {
    29.         Vector2 tmp;
    30. #if UNITY_IPHONE
    31.         if (Input.touchCount > 0)
    32.         {
    33.             tmp = Input.GetTouch(0).position;
    34.             tmp.y = Screen.height - tmp.y; // touch starts top left
    35.             if (Input.GetTouch(0).phase == TouchPhase.Began)
    36.             {
    37.                 lineList.Clear();
    38.                 done = false;
    39.             }
    40.             lineList.Add(tmp);
    41.             if (Input.GetTouch(0).phase == TouchPhase.Ended)
    42.             {
    43.                 done = true;
    44.                 ComputeStats();
    45.             }          
    46.         }
    47. #endif
    48. #if UNITY_EDITOR
    49.         tmp = Input.mousePosition;
    50.         tmp.y = Screen.height - tmp.y; // touch starts top left
    51.         if (Input.GetMouseButtonDown(0))
    52.         {
    53.             lineList.Clear();
    54.             done = false;
    55.             lineList.Add(tmp);
    56.         }
    57.         if (Input.GetMouseButtonUp(0))
    58.         {
    59.             lineList.Add(tmp);
    60.             done = true;
    61.             ComputeStats();
    62.         }
    63.         if (Input.GetMouseButton(0))
    64.         {
    65.             lineList.Add(tmp);
    66.         }
    67. #endif
    68.     }
    69.        
    70.     void OnGUI()
    71.     {
    72.         DrawList();
    73.        
    74.         if (done)
    75.         {
    76.             GUI.Label(new Rect(10, 10, 500, 25), "Center: " + vCenter.ToString());
    77.             GUI.Label(new Rect(10, 30, 500, 25), "Radius: " + vRadius.x + ".." + vRadius.y);
    78.             GUI.Label(new Rect(10, 50, 500, 25), "Angle: " + fAngle);
    79.         }
    80.     }
    81.    
    82.     void DrawList ()
    83.     {
    84.         if (Event.current.type != EventType.Repaint)
    85.             return;
    86.  
    87.         lineMaterial.SetPass(0);
    88.        
    89.         GL.PushMatrix ();
    90.          GL.Begin (GL.LINES);
    91.        
    92.             DrawLines ();
    93.  
    94.          GL.End ();
    95.         GL.PopMatrix ();
    96.        
    97.     }
    98.  
    99.     void DrawLines()
    100.     {
    101.         if (lineList.Count > 1)
    102.         {
    103.             vCenter = lineList[0];
    104.            
    105.             // draw outline
    106.             GL.Color (lineColor);
    107.             for (int i = 1; i < lineList.Count; i++)
    108.             {
    109.                 DrawLine (lineList[i-1], lineList[i]);
    110.                 vCenter += lineList[i];
    111.             }
    112.  
    113.             vCenter /= lineList.Count;
    114.            
    115.             // draw spokes
    116.             GL.Color (lineColorLight);
    117.             for (int i = 0; i < lineList.Count; i++)
    118.             {
    119.                 DrawLine (vCenter, lineList[i]);
    120.             }
    121.         }
    122.     }
    123.  
    124.     private void DrawLine (Vector2 p1, Vector2 p2)
    125.     {
    126.         GL.Vertex (p1);
    127.         GL.Vertex (p2);
    128.     }
    129.  
    130.     private void ComputeStats()
    131.     {
    132.         if (lineList.Count > 1)
    133.         {
    134.             // compute center
    135.             vCenter = Vector2.zero;
    136.             for (int i = 0; i < lineList.Count; i++)
    137.             {
    138.                 vCenter += lineList[i];
    139.             }
    140.  
    141.             vCenter /= lineList.Count;
    142.  
    143.             // get min and max radius
    144.             vRadius = Vector2.zero;
    145.             vRadius.x = 123456.0f;
    146.            
    147.             Vector2 tmp;
    148.             float len;
    149.             for (int i = 0; i < lineList.Count; i++)
    150.             {
    151.                 tmp = lineList[i] - vCenter;
    152.                 len = tmp.magnitude;
    153.                
    154.                 vRadius.x = (len < vRadius.x) ? len : vRadius.x;
    155.                 vRadius.y = (len > vRadius.y) ? len : vRadius.y;
    156.             }
    157.            
    158.             // use angles to work out completeness
    159.             // and to decide if it's a circle at all... hmm, thinks...
    160.            
    161.             Vector2 a = lineList[0] - vCenter;
    162.             fAngle = 0;
    163.             for (int i = 1; i < lineList.Count; i++)
    164.             {
    165.                 Vector2 b = lineList[i] - vCenter;
    166.                
    167.                 fAngle += Vector2.Angle(a,b);
    168.                 a = b;             
    169.             }
    170.         }
    171.     }
    172.        
    173.     private Material lineMaterial;
    174.    
    175.     private void CreateLineMaterial()
    176.     {
    177.         if( !lineMaterial ) {
    178.             lineMaterial = new Material( "Shader \"Lines/Colored Blended\" {" +
    179.                 "SubShader { Pass { " +
    180.                 "    Blend SrcAlpha OneMinusSrcAlpha " +
    181.                 "    ZWrite Off Cull Off Fog { Mode Off } " +
    182.                 "    BindChannels {" +
    183.                 "      Bind \"vertex\", vertex Bind \"color\", color }" +
    184.                 "} } }" );
    185.             lineMaterial.hideFlags = HideFlags.HideAndDontSave;
    186.             lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
    187.         }
    188.     }
    189. }
    190.  
     
  7. JFo

    JFo

    Joined:
    Dec 9, 2007
    Posts:
    217
    Krishx007 likes this.
  8. Krishx007

    Krishx007

    Joined:
    Jul 15, 2014
    Posts:
    14
    Awesome code for debugging the touches, Thank you so much for sharing ..
     
  9. DexRobinson

    DexRobinson

    Joined:
    Jul 26, 2011
    Posts:
    594
    I use FateaFrogs Finger Gestures, it's like 40 bucks or something but it does custom input so you could make custom finger gestures and have it do what ever your wanted.

    http://fingergestures.fatalfrog.com/
     
    Graham-Dunnett likes this.
  10. Shadowphax

    Shadowphax

    Joined:
    Jul 26, 2013
    Posts:
    8
    Really old post but I figure it might help someone.

    I'm currently busy with circle gestures. But I'm very lazy. So what I'm doing at the moment is having a 'gesture' game object with circle colliders placed in a circle. Initially all of them are enabled. Once the user touches down on one of them (or I place the entire object under the touch position if it is the first touch) I enable the 2 neighbouring colliders and disable the touched collider. Then I have a 'cooldown' time. If the user swipes to one of the active neighbours before the time runs out, I activate the next neighbour in that direction and set a circular momentum variable.

    I guess this is a bit of a sloppy approach and I'm guessing the performance is a bit worse than just running the math. But I figured I might as well take advantage of gameobject concept. This way is also very simple to debug as you could have some sprites that light up as the gesture is performed so you can see exactly what's going on.

    The initial scale and placement of the input surface may require some math. For example you want to use the first bit of swiping to estimate the size of the circle that the player is going to draw. Otherwise the input is going to be frustrating.