Search Unity

Swipe in all directions Touch and Mouse

Discussion in 'Scripting' started by Gustav_Bok, Jan 8, 2013.

  1. ickydime

    ickydime

    Joined:
    Nov 20, 2012
    Posts:
    54
    I made an alternative:

    This will find the angle, any angle:

    Code (CSharp):
    1. void Update () {
    2.         DetectSwipe();
    3.     }
    4.  
    5.     // Helpers
    6.     private void DetectSwipe() {
    7.         if( Input.GetMouseButtonDown(0) ) {
    8.             _startTouchPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    9.         } else if ( Input.GetMouseButtonUp (0) ) {
    10.             Vector2 endTouchPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    11.             Vector2 swipe = _startTouchPosition - endTouchPosition;
    12.             if(swipe.magnitude < MIN_SWIPE_LENGTH) {
    13.                 _startTouchPosition = Vector2.zero;
    14.                 return;
    15.             }
    16.             var angle = Mathf.Atan2 (endTouchPosition.y - _startTouchPosition.y, endTouchPosition.x - _startTouchPosition.x)*Mathf.Rad2Deg;
    17.             Main.Instance.Swipe (angle);
    18.             _startTouchPosition = Vector2.zero;
    19.        
    And then if you want to detect the direction:

    Code (CSharp):
    1. public void Jump(float angle) {
    2.  
    3.         if (angle < -157.5 || angle > 157.5) {
    4.             // Left
    5.         } else if ( angle < -112.5 ) {
    6.             // Down Left
    7.         } else if (angle < -67.5 ) {
    8.             // Down
    9.         } else if (angle < -22.5) {
    10.             // Down Right
    11.         } else if (angle < 22.5) {
    12.             // Right
    13.         } else if (angle < 67.5) {
    14.             // Up Right
    15.         } else if (angle < 112.5) {
    16.             // Up
    17.         } else {
    18.             // Up Left;
    19.         }
    20.     }
     
  2. zigglr

    zigglr

    Joined:
    Sep 28, 2015
    Posts:
    82
    For this:

    if(currentSwipe.y>0 currentSwipe.x>-0.5f currentSwipe.x< 0.5f)

    Something needs to go after the 0 and the -0.5f what should I put?
     
  3. KGC

    KGC

    Joined:
    Oct 2, 2014
    Posts:
    11
    So I rewrote the SwipeManager implementation by Brad Keys for use in our own game (supports touch and mouse swiping).

    I wanted more control over the actual Swipe and add more values to pass on to other scripts.

    Also, I prefer to use event-based approaches in general, so i am using System.Action to pass on a struct with the additional data.

    This completely separates the SwipeManager from all game logic, as it simply packs swipe data in a nice format and passes it on to anybody listening.

    Furthermore, I also incorporated angle checking for 8 degree swipe direction detection (and fixed a "bug" in the original code with diagonal swipes being reported as "None" rather than the closest). I know that was probably intentional, but still - I had another use case ;)

    EDIT 2015-12-11:
    Added missing InputHelper.cs and TouchCreator.cs files, and updated SwipeManager to also accept long press! :)

    Usage:
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. [RequireComponent(typeof(SwipeManager))]
    7. public class InputController : MonoBehaviour
    8. {
    9.     void Start()
    10.     {
    11.         SwipeManager swipeManager = GetComponent<SwipeManager>();
    12.         swipeManager.onSwipe += HandleSwipe;
    13.         swipeManager.onLongPress += HandleLongPress;
    14.     }
    15.  
    16.     void HandleSwipe(SwipeAction swipeAction)
    17.     {
    18.         Debug.LogFormat("HandleSwipe: {0}", swipeAction);
    19.     }
    20.    
    21.     void HandleLongPress(SwipeAction swipeAction)
    22.     {
    23.         Debug.LogFormat("HandleLongPress: {0}", swipeAction);
    24.     }
    25. }
    26.  
    27.  

    Source:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public struct SwipeAction
    5. {
    6.     public SwipeDirection direction;
    7.     public Vector2 rawDirection;
    8.     public Vector2 startPosition;
    9.     public Vector2 endPosition;
    10.     public float startTime;
    11.     public float endTime;
    12.     public float duration;
    13.     public bool longPress;
    14.     public float distance;
    15.     public float longestDistance;
    16.  
    17.     public override string ToString()
    18.     {
    19.         return string.Format("[SwipeAction: {0}, From {1}, To {2}, Delta {3}, Time {4:0.00}s]", direction, rawDirection, startPosition, endPosition, duration);
    20.     }
    21. }
    22.  
    23. public enum SwipeDirection
    24. {
    25.     None, // Basically means an invalid swipe
    26.     Up,
    27.     UpRight,
    28.     Right,
    29.     DownRight,
    30.     Down,
    31.     DownLeft,
    32.     Left,
    33.     UpLeft
    34. }
    35.  
    36. /// <summary>
    37. /// Swipe manager.
    38. /// BASED ON: http://forum.unity3d.com/threads/swipe-in-all-directions-touch-and-mouse.165416/#post-1516893
    39. /// </summary>
    40. public class SwipeManager : MonoBehaviour
    41. {
    42.     public System.Action<SwipeAction> onSwipe;
    43.     public System.Action<SwipeAction> onLongPress;
    44.  
    45.     [Range(0f, 200f)]
    46.     public float minSwipeLength = 100f;
    47.  
    48.     public float longPressDuration = 0.5f;
    49.  
    50.     Vector2 currentSwipe;
    51.     SwipeAction currentSwipeAction = new SwipeAction();
    52.  
    53.     void Update()
    54.     {
    55.         DetectSwipe();
    56.     }
    57.    
    58.     public void DetectSwipe()
    59.     {
    60.         var touches = InputHelper.GetTouches();
    61.         if (touches.Count > 0)
    62.         {
    63.             Touch t = touches[0];
    64.            
    65.             if (t.phase == TouchPhase.Began)
    66.             {
    67.                 ResetCurrentSwipeAction(t);
    68.             }
    69.  
    70.             if (t.phase == TouchPhase.Moved || t.phase == TouchPhase.Stationary)
    71.             {
    72.                 UpdateCurrentSwipeAction(t);
    73.                 if(!currentSwipeAction.longPress && currentSwipeAction.duration > longPressDuration && currentSwipeAction.longestDistance < minSwipeLength)
    74.                 {
    75.                     currentSwipeAction.direction = SwipeDirection.None; // Invalidate current swipe action
    76.                     currentSwipeAction.longPress = true;
    77.                     if(onLongPress != null)
    78.                     {
    79.                         onLongPress(currentSwipeAction); // Fire event
    80.                     }
    81.                     return;
    82.                 }
    83.             }
    84.  
    85.             if (t.phase == TouchPhase.Ended)
    86.             {
    87.                 UpdateCurrentSwipeAction(t);
    88.                
    89.                 // Make sure it was a legit swipe, not a tap, or long press
    90.                 if (currentSwipeAction.distance < minSwipeLength || currentSwipeAction.longPress) // Didnt swipe enough or this is a long press
    91.                 {
    92.                     currentSwipeAction.direction = SwipeDirection.None; // Invalidate current swipe action
    93.                     return;
    94.                 }
    95.  
    96.                 if(onSwipe != null)
    97.                 {
    98.                     onSwipe(currentSwipeAction); // Fire event
    99.                 }
    100.             }
    101.         }
    102.     }
    103.  
    104.     void ResetCurrentSwipeAction(Touch t)
    105.     {
    106.         currentSwipeAction.duration = 0f;
    107.         currentSwipeAction.distance = 0f;
    108.         currentSwipeAction.longestDistance = 0f;
    109.         currentSwipeAction.longPress = false;
    110.         currentSwipeAction.startPosition = new Vector2(t.position.x, t.position.y);
    111.         currentSwipeAction.startTime = Time.time;
    112.         currentSwipeAction.endPosition = currentSwipeAction.startPosition;
    113.         currentSwipeAction.endTime = currentSwipeAction.startTime;
    114.     }
    115.  
    116.     void UpdateCurrentSwipeAction(Touch t)
    117.     {
    118.         currentSwipeAction.endPosition = new Vector2(t.position.x, t.position.y);
    119.         currentSwipeAction.endTime = Time.time;
    120.         currentSwipeAction.duration = currentSwipeAction.endTime - currentSwipeAction.startTime;
    121.         currentSwipe = currentSwipeAction.endPosition - currentSwipeAction.startPosition;
    122.         currentSwipeAction.rawDirection = currentSwipe;
    123.         currentSwipeAction.direction = GetSwipeDirection(currentSwipe);
    124.         currentSwipeAction.distance = Vector2.Distance(currentSwipeAction.startPosition, currentSwipeAction.endPosition);
    125.         if (currentSwipeAction.distance > currentSwipeAction.longestDistance) // If new distance is longer than previously longest
    126.         {
    127.             currentSwipeAction.longestDistance = currentSwipeAction.distance; // Update longest distance
    128.         }
    129.     }
    130.  
    131.     SwipeDirection GetSwipeDirection(Vector2 direction)
    132.     {
    133.         var angle = Vector2.Angle(Vector2.up, direction.normalized); // Degrees
    134.         var swipeDirection = SwipeDirection.None;
    135.  
    136.         if(direction.x > 0) // Right
    137.         {
    138.             if(angle < 22.5f) // 0.0 - 22.5
    139.             {
    140.                 swipeDirection = SwipeDirection.Up;
    141.             }
    142.             else if(angle < 67.5f) // 22.5 - 67.5
    143.             {
    144.                 swipeDirection = SwipeDirection.UpRight;
    145.             }
    146.             else if(angle < 112.5f) // 67.5 - 112.5
    147.             {
    148.                 swipeDirection = SwipeDirection.Right;
    149.             }
    150.             else if(angle < 157.5f) // 112.5 - 157.5
    151.             {
    152.                 swipeDirection = SwipeDirection.DownRight;
    153.             }
    154.             else if(angle < 180.0f) // 157.5 - 180.0
    155.             {
    156.                 swipeDirection = SwipeDirection.Down;
    157.             }
    158.         }
    159.         else // Left
    160.         {
    161.             if(angle < 22.5f) // 0.0 - 22.5
    162.             {
    163.                 swipeDirection = SwipeDirection.Up;
    164.             }
    165.             else if(angle < 67.5f) // 22.5 - 67.5
    166.             {
    167.                 swipeDirection = SwipeDirection.UpLeft;
    168.             }
    169.             else if(angle < 112.5f) // 67.5 - 112.5
    170.             {
    171.                 swipeDirection = SwipeDirection.Left;
    172.             }
    173.             else if(angle < 157.5f) // 112.5 - 157.5
    174.             {
    175.                 swipeDirection = SwipeDirection.DownLeft;
    176.             }
    177.             else if(angle < 180.0f) // 157.5 - 180.0
    178.             {
    179.                 swipeDirection = SwipeDirection.Down;
    180.             }
    181.         }
    182.  
    183.         return swipeDirection;
    184.     }
    185. }
    186.  
    187.  

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. /// <summary>
    6. /// Input helper.
    7. /// SOURCE: http://answers.unity3d.com/answers/956579/view.html
    8. /// </summary>
    9. public static class InputHelper
    10. {
    11.     private static TouchCreator lastFakeTouch;
    12.    
    13.     public static List<Touch> GetTouches()
    14.     {
    15.         List<Touch> touches = new List<Touch>();
    16.         touches.AddRange(Input.touches);
    17.         // Uncomment if you want it only to allow mouse swipes in the Unity Editor
    18.         //#if UNITY_EDITOR
    19.         if (lastFakeTouch == null)
    20.         {
    21.             lastFakeTouch = new TouchCreator();
    22.         }
    23.         if (Input.GetMouseButtonDown(0))
    24.         {
    25.             lastFakeTouch.phase = TouchPhase.Began;
    26.             lastFakeTouch.deltaPosition = new Vector2(0, 0);
    27.             lastFakeTouch.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    28.             lastFakeTouch.fingerId = 0;
    29.         }
    30.         else if (Input.GetMouseButtonUp(0))
    31.         {
    32.             lastFakeTouch.phase = TouchPhase.Ended;
    33.             Vector2 newPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    34.             lastFakeTouch.deltaPosition = newPosition - lastFakeTouch.position;
    35.             lastFakeTouch.position = newPosition;
    36.             lastFakeTouch.fingerId = 0;
    37.         }
    38.         else if (Input.GetMouseButton(0))
    39.         {
    40.             lastFakeTouch.phase = TouchPhase.Moved;
    41.             Vector2 newPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    42.             lastFakeTouch.deltaPosition = newPosition - lastFakeTouch.position;
    43.             lastFakeTouch.position = newPosition;
    44.             lastFakeTouch.fingerId = 0;
    45.         }
    46.         else
    47.         {
    48.             lastFakeTouch = null;
    49.         }
    50.         if (lastFakeTouch != null)
    51.         {
    52.             touches.Add(lastFakeTouch.Create());
    53.         }
    54.         // Uncomment if you want it only to allow mouse swipes in the Unity Editor
    55.         //#endif
    56.        
    57.         return touches;  
    58.     }
    59. }
    60.  
    61.  

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Reflection;
    3. using System.Collections.Generic;
    4.  
    5. /// <summary>
    6. /// Touch creator.
    7. /// BASED ON: http://answers.unity3d.com/answers/801637/view.html
    8. /// </summary>
    9. public class TouchCreator
    10. {
    11.     static BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
    12.     static Dictionary<string, FieldInfo> fields;
    13.    
    14.     object touch;
    15.    
    16.     public float deltaTime { get { return ((Touch)touch).deltaTime; } set { fields ["m_TimeDelta"].SetValue(touch, value); } }
    17.     public int tapCount { get { return ((Touch)touch).tapCount; } set { fields ["m_TapCount"].SetValue(touch, value); } }
    18.     public TouchPhase phase { get { return ((Touch)touch).phase; } set { fields ["m_Phase"].SetValue(touch, value); } }
    19.     public Vector2 deltaPosition { get { return ((Touch)touch).deltaPosition; } set { fields ["m_PositionDelta"].SetValue(touch, value); } }
    20.     public int fingerId { get { return ((Touch)touch).fingerId; } set { fields ["m_FingerId"].SetValue(touch, value); } }
    21.     public Vector2 position { get { return ((Touch)touch).position; } set { fields ["m_Position"].SetValue(touch, value); } }
    22.     public Vector2 rawPosition { get { return ((Touch)touch).rawPosition; } set { fields ["m_RawPosition"].SetValue(touch, value); } }
    23.    
    24.     public Touch Create()
    25.     {
    26.         return (Touch)touch;
    27.     }
    28.    
    29.     public TouchCreator()
    30.     {
    31.         touch = new Touch();
    32.     }
    33.    
    34.     static TouchCreator()
    35.     {
    36.         fields = new Dictionary<string, FieldInfo>();
    37.         foreach (var f in typeof(Touch).GetFields(flags))
    38.         {
    39.             fields.Add(f.Name, f);
    40.             //Debug.Log("name: " + f.Name); // Use this to find the names of hidden private fields
    41.         }
    42.     }
    43. }
    44.  
    45.  
     
    Last edited: Dec 11, 2015
    MD_Reptile likes this.
  4. Massive-Brain

    Massive-Brain

    Joined:
    Dec 17, 2014
    Posts:
    2
    hi KGC would you please edit your script and provide it with mouse swipe

    this going to be very helpful for me thank you very much in advance
     
  5. KGC

    KGC

    Joined:
    Oct 2, 2014
    Posts:
    11
    Updated my answer :)
    Added missing InputHelper.cs and TouchCreator.cs files, and updated SwipeManager to also accept long press! :)
     
  6. clearrose

    clearrose

    Joined:
    Oct 24, 2012
    Posts:
    349

    Hi, I have another question. How can I convert this:

    Code (CSharp):
    1. //If the player presses the second mouse button.....
    2.             if (Input.GetKey(KeyCode.Mouse1))
    3.             {
    4.                 //Moves player forward on X-axis
    5.                 Turtle.MovePosition(Turtle.position + velocity * Time.smoothDeltaTime);
    6.  
    7.                 //Sets the animation speed of the player. Speeds up the animation.
    8.                 TurtlePlayer.speed = 2;
    9.  
    10.                 //Starts coroutine to reset the player's animation speed back to nomral.
    11.                 StartCoroutine (TurtleSwimReset());
    12.             }
    to use your touch scripts? I want my player to move forward with the right swipe and backwards with the left.
     
  7. KGC

    KGC

    Joined:
    Oct 2, 2014
    Posts:
    11
    It looks like your code executes on every frame, which means that it is not so simple to convert. What i would do is take the contents of your IF statement and put it inside the HandleSwipe() function that i wrote in the "Usage Example". It would look something like this:

    Code (CSharp):
    1.  
    2. // Example code
    3. [RequireComponent(typeof(SwipeManager))]
    4. public class Turtle : MonoBehavior
    5. {
    6.     public TurtleState turtleState = TurtleState.Idle;
    7.  
    8.     public enum TurtleState
    9.     {
    10.         Idle,
    11.         MovingLeft,
    12.         MovingRight
    13.     }
    14.  
    15.     void Start()
    16.     {
    17.         SwipeManager swipeManager = GetComponent<SwipeManager>();
    18.         swipeManager.onSwipe += HandleSwipe;
    19.     }
    20.    
    21.     void HandleSwipe(SwipeAction swipeAction)
    22.     {
    23.         if(swipeAction.direction == SwipeDirection.Right) // If the player swipes right
    24.         {
    25.             turtleState = TurtleState.MovingRight; // Make the turtle move to the right
    26.         }
    27.         // TODO: Add code for other directions if needed
    28.     }
    29.  
    30.     void Update()
    31.     {
    32.         if(turtleState == TurtleState.MovingRight)
    33.         {
    34.             DoMoveRight(); // Make the turtle move right
    35.             // TODO: Figure out how to stop the turtle from moving to the right all the time. You could use a timer, a coroutine, animation triggers etc.
    36.         }
    37.     }
    38.  
    39.     void DoMoveRight()
    40.     {
    41.         // TODO: Refactor so it works when called every frame, where you want the turtle to move to the right
    42.    
    43.         //Moves player forward on X-axis
    44.         Turtle.MovePosition(Turtle.position + velocity * Time.smoothDeltaTime);
    45.  
    46.         //Sets the animation speed of the player. Speeds up the animation.
    47.         TurtlePlayer.speed = 2;
    48.  
    49.         //Starts coroutine to reset the player's animation speed back to nomral.
    50.         StartCoroutine (TurtleSwimReset());
    51.     }
    52. }
    53.  
     
  8. clearrose

    clearrose

    Joined:
    Oct 24, 2012
    Posts:
    349

    thanks soo much !
     
  9. kaye17

    kaye17

    Joined:
    Aug 29, 2013
    Posts:
    3
    can someone convert it in Javascript? Thank you!
     
  10. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,595
    I further modified KGC's version of Brad Keys scripts, and added taps as being any touch shorter in time than a long press and not long enough distance to be a swipe, and lowered default value of a long press to 2.5. I also added a check for whether or not a uGUI component (buttons, joysticks, whatever) is being interacted with, and don't do swipes/taps/long-presses if the touch or mouse goes over the objects in the UI.

    I also added a "canceled" touch condition in there somewhere, which may or may not be needed/helpful.

    No guarantee's there aren't errors I haven't noticed!

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. [RequireComponent(typeof(SwipeManager))]
    6. public class InputController : MonoBehaviour
    7. {
    8.     void Start()
    9.     {
    10.         SwipeManager swipeManager = GetComponent<SwipeManager>();
    11.         swipeManager.onSwipe += HandleSwipe;
    12.         swipeManager.onLongPress += HandleLongPress;
    13.         swipeManager.onTap += HandleTap;
    14.     }
    15.  
    16.     void HandleSwipe(SwipeAction swipeAction)
    17.     {
    18.         Debug.LogFormat("HandleSwipe: {0}", swipeAction);
    19.         if (swipeAction.direction == SwipeDirection.Right || swipeAction.direction == SwipeDirection.DownRight || swipeAction.direction == SwipeDirection.UpRight)
    20.         {
    21.             // Right Swipe
    22.         }
    23.         else if (swipeAction.direction == SwipeDirection.Left || swipeAction.direction == SwipeDirection.UpLeft || swipeAction.direction == SwipeDirection.DownLeft)
    24.         {
    25.             // Left Swipe
    26.         }
    27.     }
    28.  
    29.     void HandleLongPress(SwipeAction swipeAction)
    30.     {
    31.         Debug.LogFormat("HandleLongPress: {0}", swipeAction);
    32.     }
    33.  
    34.     void HandleTap(SwipeAction swipeAction)
    35.     {
    36.         Debug.LogFormat("HandleTap: {0}", swipeAction);
    37.     }
    38. }

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4. using System.Collections;
    5.  
    6. public struct SwipeAction
    7. {
    8.     public SwipeDirection direction;
    9.     public Vector2 rawDirection;
    10.     public Vector2 startPosition;
    11.     public Vector2 endPosition;
    12.     public float startTime;
    13.     public float endTime;
    14.     public float duration;
    15.     public bool longPress;
    16.     public bool tap;
    17.     public float distance;
    18.     public float longestDistance;
    19.  
    20.     public override string ToString()
    21.     {
    22.         return string.Format("[SwipeAction: {0}, From {1}, To {2}, Delta {3}, Time {4:0.00}s]", direction, rawDirection, startPosition, endPosition, duration);
    23.     }
    24. }
    25.  
    26. public enum SwipeDirection
    27. {
    28.     None, // Basically means an invalid swipe
    29.     Up,
    30.     UpRight,
    31.     Right,
    32.     DownRight,
    33.     Down,
    34.     DownLeft,
    35.     Left,
    36.     UpLeft
    37. }
    38.  
    39. /// <summary>
    40. /// Swipe manager.
    41. /// BASED ON: http://forum.unity3d.com/threads/swipe-in-all-directions-touch-and-mouse.165416/#post-1516893
    42. /// </summary>
    43. public class SwipeManager : MonoBehaviour
    44. {
    45.     public System.Action<SwipeAction> onSwipe;
    46.     public System.Action<SwipeAction> onLongPress;
    47.     public System.Action<SwipeAction> onTap;
    48.  
    49.     [Range(0f, 200f)]
    50.     public float minSwipeLength = 100f;
    51.  
    52.     public float longPressDuration = 0.5f;
    53.  
    54.     Vector2 currentSwipe;
    55.     SwipeAction currentSwipeAction = new SwipeAction();
    56.  
    57.     void Update()
    58.     {
    59.         DetectSwipe();
    60.     }
    61.  
    62.     public void DetectSwipe()
    63.     {
    64.         var touches = InputHelper.GetTouches();
    65.         if (touches.Count > 0)
    66.         {
    67.             Touch t = touches[0];
    68.  
    69.             if (EventSystem.current.IsPointerOverGameObject() && EventSystem.current.currentSelectedGameObject != null)
    70.             {
    71.                 //Debug.Log("touch/mouse over a uGUI element: " + EventSystem.current.currentSelectedGameObject.name);
    72.                 ResetCurrentSwipeAction(t);
    73.                 return;
    74.             }
    75.  
    76.             if (t.phase == TouchPhase.Began)
    77.             {
    78.                 ResetCurrentSwipeAction(t);
    79.             }
    80.  
    81.             if (t.phase == TouchPhase.Moved || t.phase == TouchPhase.Stationary)
    82.             {
    83.                 UpdateCurrentSwipeAction(t);
    84.                 if (!currentSwipeAction.longPress && currentSwipeAction.duration > longPressDuration && currentSwipeAction.longestDistance < minSwipeLength)
    85.                 {
    86.                     currentSwipeAction.direction = SwipeDirection.None; // Invalidate current swipe action
    87.                     currentSwipeAction.longPress = true;
    88.                     if (onLongPress != null)
    89.                     {
    90.                         onLongPress(currentSwipeAction); // Fire event
    91.                     }
    92.                     return;
    93.                 }
    94.             }
    95.  
    96.             if (t.phase == TouchPhase.Ended || t.phase == TouchPhase.Canceled)
    97.             {
    98.                 UpdateCurrentSwipeAction(t);
    99.  
    100.                 if (currentSwipeAction.duration < longPressDuration && currentSwipeAction.longestDistance < minSwipeLength) // this is tap
    101.                 {
    102.                     currentSwipeAction.direction = SwipeDirection.None; // Invalidate current swipe action
    103.                     currentSwipeAction.tap = true;
    104.                     if (onTap != null)
    105.                     {
    106.                         onTap(currentSwipeAction);
    107.                     }
    108.                     return;
    109.                 }
    110.  
    111.                 // Make sure it was a legit swipe, not a tap, or long press
    112.                 if (currentSwipeAction.distance < minSwipeLength || currentSwipeAction.longPress) // Didnt swipe enough or this is a long press
    113.                 {
    114.                     currentSwipeAction.direction = SwipeDirection.None; // Invalidate current swipe action
    115.                     return;
    116.                 }
    117.  
    118.                 if (onSwipe != null)
    119.                 {
    120.                     onSwipe(currentSwipeAction); // Fire event
    121.                 }
    122.             }
    123.         }
    124.     }
    125.  
    126.     void ResetCurrentSwipeAction(Touch t)
    127.     {
    128.         currentSwipeAction.duration = 0f;
    129.         currentSwipeAction.distance = 0f;
    130.         currentSwipeAction.longestDistance = 0f;
    131.         currentSwipeAction.longPress = false;
    132.         currentSwipeAction.tap = false;
    133.         currentSwipeAction.startPosition = new Vector2(t.position.x, t.position.y);
    134.         currentSwipeAction.startTime = Time.time;
    135.         currentSwipeAction.endPosition = currentSwipeAction.startPosition;
    136.         currentSwipeAction.endTime = currentSwipeAction.startTime;
    137.     }
    138.  
    139.     void UpdateCurrentSwipeAction(Touch t)
    140.     {
    141.         currentSwipeAction.endPosition = new Vector2(t.position.x, t.position.y);
    142.         currentSwipeAction.endTime = Time.time;
    143.         currentSwipeAction.duration = currentSwipeAction.endTime - currentSwipeAction.startTime;
    144.         currentSwipe = currentSwipeAction.endPosition - currentSwipeAction.startPosition;
    145.         currentSwipeAction.rawDirection = currentSwipe;
    146.         currentSwipeAction.direction = GetSwipeDirection(currentSwipe);
    147.         currentSwipeAction.distance = Vector2.Distance(currentSwipeAction.startPosition, currentSwipeAction.endPosition);
    148.         if (currentSwipeAction.distance > currentSwipeAction.longestDistance) // If new distance is longer than previously longest
    149.         {
    150.             currentSwipeAction.longestDistance = currentSwipeAction.distance; // Update longest distance
    151.         }
    152.     }
    153.  
    154.     SwipeDirection GetSwipeDirection(Vector2 direction)
    155.     {
    156.         var angle = Vector2.Angle(Vector2.up, direction.normalized); // Degrees
    157.         var swipeDirection = SwipeDirection.None;
    158.  
    159.         if (direction.x > 0) // Right
    160.         {
    161.             if (angle < 22.5f) // 0.0 - 22.5
    162.             {
    163.                 swipeDirection = SwipeDirection.Up;
    164.             }
    165.             else if (angle < 67.5f) // 22.5 - 67.5
    166.             {
    167.                 swipeDirection = SwipeDirection.UpRight;
    168.             }
    169.             else if (angle < 112.5f) // 67.5 - 112.5
    170.             {
    171.                 swipeDirection = SwipeDirection.Right;
    172.             }
    173.             else if (angle < 157.5f) // 112.5 - 157.5
    174.             {
    175.                 swipeDirection = SwipeDirection.DownRight;
    176.             }
    177.             else if (angle < 180.0f) // 157.5 - 180.0
    178.             {
    179.                 swipeDirection = SwipeDirection.Down;
    180.             }
    181.         }
    182.         else // Left
    183.         {
    184.             if (angle < 22.5f) // 0.0 - 22.5
    185.             {
    186.                 swipeDirection = SwipeDirection.Up;
    187.             }
    188.             else if (angle < 67.5f) // 22.5 - 67.5
    189.             {
    190.                 swipeDirection = SwipeDirection.UpLeft;
    191.             }
    192.             else if (angle < 112.5f) // 67.5 - 112.5
    193.             {
    194.                 swipeDirection = SwipeDirection.Left;
    195.             }
    196.             else if (angle < 157.5f) // 112.5 - 157.5
    197.             {
    198.                 swipeDirection = SwipeDirection.DownLeft;
    199.             }
    200.             else if (angle < 180.0f) // 157.5 - 180.0
    201.             {
    202.                 swipeDirection = SwipeDirection.Down;
    203.             }
    204.         }
    205.  
    206.         return swipeDirection;
    207.     }
    208. }
    209.  

    InputHelper.cs and TouchCreator.cs are unchanged. I thought this was nice, because I could unify my mobile input code, rather than have a hacky separate script watch for taps...

    EDIT: I have noticed ignoring the GUI works in editor, but not on actual device (android)... I will investigate and edit this post if I get it working right! Maybe @KGC could help!

    EDIT2: Found a free asset which provides a better solution to blocking input through uGUI elements - https://www.assetstore.unity3d.com/en/#!/content/30111
     
    Last edited: Apr 19, 2016
  11. Dantas.Sousa

    Dantas.Sousa

    Joined:
    Nov 23, 2014
    Posts:
    1
    someone can help me?

    how to make the command to run before removing the finger from the screen?

    like temple run 2, the command is actived just after de swipe without removing de finger.
     
  12. Brad-Keys

    Brad-Keys

    Joined:
    May 1, 2006
    Posts:
    161
    Glad to see this post has been so useful to people. I found myself needing to use this original code again recently, so I looked over all the great improvements people made in this thread and then combined them into a simplified version of the script. I believe it will be useful to most people wanting this.

    Improvements
    - Option to check 8 directions or 4 [inspector option]
    - Uses physical screen size (inches) for min swipe distance [inspector option]
    - Detects mouse swipe and touch swipe
    - Can subscribe to OnSwipeDetected event or check via Update loop yourself
    - Simplified code

    Improvements (Feb 21, 2017 Edit)
    - Option for the swipe to trigger when min swipe length is reached [inspector option]
    - Swipe velocity now provided in OnSwipeDetected event & SwipeManager.swipeVelocity

    Improvements (June 26, 2017 Edit)
    - Fixed issue with mouse swipes not resetting (as pointed out in comments)
    - Added IsSwiping() function
    - Attached script to post
    - Improved instructions and examples

    Instructions
    Add SwipeManager.cs to a GameObject in your scene. Note: This script does not detect swipes on the GameObject you attach the script to. It detects swipes in general and should only exist on one persistent GameObject.

    Example 1 - Checking via Update
    Code (csharp):
    1.  
    2. void Update ()
    3. {
    4.     if (SwipeManager.IsSwipingLeft()) {
    5.         // do something
    6.     }
    7.  
    8.     // OR
    9.  
    10.     if (SwipeManager.IsSwiping()) {
    11.         // do something
    12.     }
    13. }
    14.  
    Example 2 - Checking via event
    Code (csharp):
    1.  
    2. void Start ()
    3. {
    4.     SwipeManager.OnSwipeDetected += OnSwipeDetected;
    5. }
    6.  
    7. void OnSwipeDetected (Swipe direction, Vector2 swipeVelocity)
    8. {
    9.     // do something with direction or the velocity of the swipe
    10. }
    11.  

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5.  
    6. class CardinalDirection
    7. {
    8.     public static readonly Vector2 Up = new Vector2 (0, 1);
    9.     public static readonly Vector2 Down = new Vector2 (0, -1);
    10.     public static readonly Vector2 Right = new Vector2 (1, 0);
    11.     public static readonly Vector2 Left = new Vector2 (-1, 0);
    12.     public static readonly Vector2 UpRight = new Vector2 (1, 1);
    13.     public static readonly Vector2 UpLeft = new Vector2 (-1, 1);
    14.     public static readonly Vector2 DownRight = new Vector2 (1, -1);
    15.     public static readonly Vector2 DownLeft = new Vector2 (-1, -1);
    16. }
    17.  
    18. public enum Swipe
    19. {
    20.     None,
    21.     Up,
    22.     Down,
    23.     Left,
    24.     Right,
    25.     UpLeft,
    26.     UpRight,
    27.     DownLeft,
    28.     DownRight
    29. };
    30.  
    31. public class SwipeManager : MonoBehaviour
    32. {
    33.     #region Inspector Variables
    34.  
    35.     [Tooltip("Min swipe distance (inches) to register as swipe")]
    36.     [SerializeField] float minSwipeLength = 0.5f;
    37.  
    38.     [Tooltip("If true, a swipe is counted when the min swipe length is reached. If false, a swipe is counted when the touch/click ends.")]
    39.     [SerializeField] bool triggerSwipeAtMinLength = false;
    40.  
    41.     [Tooltip("Whether to detect eight or four cardinal directions")]
    42.     [SerializeField] bool useEightDirections = false;
    43.  
    44.     #endregion
    45.  
    46.     const float eightDirAngle = 0.906f;
    47.     const float fourDirAngle = 0.5f;
    48.     const float defaultDPI = 72f;
    49.     const float dpcmFactor = 2.54f;
    50.  
    51.     static Dictionary<Swipe, Vector2> cardinalDirections = new Dictionary<Swipe, Vector2> ()
    52.     {
    53.         { Swipe.Up,         CardinalDirection.Up                 },
    54.         { Swipe.Down,         CardinalDirection.Down             },
    55.         { Swipe.Right,         CardinalDirection.Right             },
    56.         { Swipe.Left,         CardinalDirection.Left             },
    57.         { Swipe.UpRight,     CardinalDirection.UpRight             },
    58.         { Swipe.UpLeft,     CardinalDirection.UpLeft             },
    59.         { Swipe.DownRight,     CardinalDirection.DownRight         },
    60.         { Swipe.DownLeft,     CardinalDirection.DownLeft         }
    61.     };
    62.  
    63.     public delegate void OnSwipeDetectedHandler(Swipe swipeDirection, Vector2 swipeVelocity);
    64.  
    65.     static OnSwipeDetectedHandler _OnSwipeDetected;
    66.     public static event OnSwipeDetectedHandler OnSwipeDetected
    67.     {
    68.         add {
    69.             _OnSwipeDetected += value;
    70.             autoDetectSwipes = true;
    71.         }
    72.         remove {
    73.             _OnSwipeDetected -= value;
    74.         }
    75.     }
    76.  
    77.     public static Vector2 swipeVelocity;
    78.  
    79.     static float dpcm;
    80.     static float swipeStartTime;
    81.     static float swipeEndTime;
    82.     static bool autoDetectSwipes;
    83.     static bool swipeEnded;
    84.     static Swipe swipeDirection;
    85.     static Vector2 firstPressPos;
    86.     static Vector2 secondPressPos;
    87.     static SwipeManager instance;
    88.  
    89.  
    90.     void Awake ()
    91.     {
    92.         instance = this;
    93.         float dpi = (Screen.dpi == 0) ? defaultDPI : Screen.dpi;
    94.         dpcm = dpi / dpcmFactor;
    95.     }
    96.  
    97.     void Update ()
    98.     {
    99.         if (autoDetectSwipes) {
    100.             DetectSwipe();
    101.         }
    102.     }
    103.  
    104.     /// <summary>
    105.     /// Attempts to detect the current swipe direction.
    106.     /// Should be called over multiple frames in an Update-like loop.
    107.     /// </summary>
    108.     static void DetectSwipe ()
    109.     {
    110.         if (GetTouchInput() || GetMouseInput()) {
    111.             // Swipe already ended, don't detect until a new swipe has begun
    112.             if (swipeEnded) {
    113.                 return;
    114.             }
    115.  
    116.             Vector2 currentSwipe =  secondPressPos - firstPressPos;
    117.             float swipeCm = currentSwipe.magnitude / dpcm;
    118.  
    119.             // Check the swipe is long enough to count as a swipe (not a touch, etc)
    120.             if (swipeCm < instance.minSwipeLength) {
    121.                 // Swipe was not long enough, abort
    122.                 if (!instance.triggerSwipeAtMinLength) {
    123.                     if (Application.isEditor) {
    124.                         Debug.Log("[SwipeManager] Swipe was not long enough.");
    125.                     }
    126.  
    127.                     swipeDirection = Swipe.None;
    128.                 }
    129.  
    130.                 return;
    131.             }
    132.  
    133.             swipeEndTime = Time.time;
    134.             swipeVelocity = currentSwipe * (swipeEndTime - swipeStartTime);
    135.             swipeDirection = GetSwipeDirByTouch(currentSwipe);
    136.             swipeEnded = true;
    137.  
    138.             if (_OnSwipeDetected != null) {
    139.                 _OnSwipeDetected(swipeDirection, swipeVelocity);
    140.             }
    141.         } else {
    142.             swipeDirection = Swipe.None;
    143.         }
    144.     }
    145.  
    146.     public static bool IsSwiping            () {    return swipeDirection != Swipe.None;          }
    147.     public static bool IsSwipingRight        () {     return IsSwipingDirection(Swipe.Right);           }
    148.     public static bool IsSwipingLeft         () {     return IsSwipingDirection(Swipe.Left);             }
    149.     public static bool IsSwipingUp           () {     return IsSwipingDirection(Swipe.Up);             }
    150.     public static bool IsSwipingDown         () {     return IsSwipingDirection(Swipe.Down);             }
    151.     public static bool IsSwipingDownLeft     () {     return IsSwipingDirection(Swipe.DownLeft);         }
    152.     public static bool IsSwipingDownRight    () {     return IsSwipingDirection(Swipe.DownRight);       }
    153.     public static bool IsSwipingUpLeft       () {     return IsSwipingDirection(Swipe.UpLeft);         }
    154.     public static bool IsSwipingUpRight      () {     return IsSwipingDirection(Swipe.UpRight);       }
    155.  
    156.     #region Helper Functions
    157.  
    158.     static bool GetTouchInput ()
    159.     {
    160.         if (Input.touches.Length > 0) {
    161.             Touch t = Input.GetTouch(0);
    162.  
    163.             // Swipe/Touch started
    164.             if (t.phase == TouchPhase.Began) {
    165.                 firstPressPos = t.position;
    166.                 swipeStartTime = Time.time;
    167.                 swipeEnded = false;
    168.             // Swipe/Touch ended
    169.             } else if (t.phase == TouchPhase.Ended) {
    170.                 secondPressPos = t.position;
    171.                 return true;
    172.             // Still swiping/touching
    173.             } else {
    174.                 // Could count as a swipe if length is long enough
    175.                 if (instance.triggerSwipeAtMinLength) {
    176.                     return true;
    177.                 }
    178.             }
    179.         }
    180.  
    181.         return false;
    182.     }
    183.  
    184.     static bool GetMouseInput ()
    185.     {
    186.         // Swipe/Click started
    187.         if (Input.GetMouseButtonDown(0)) {
    188.             firstPressPos = (Vector2)Input.mousePosition;
    189.             swipeStartTime = Time.time;
    190.             swipeEnded = false;
    191.         // Swipe/Click ended
    192.         } else if (Input.GetMouseButtonUp(0)) {
    193.             secondPressPos = (Vector2)Input.mousePosition;
    194.             return true;
    195.         // Still swiping/clicking
    196.         } else {
    197.             // Could count as a swipe if length is long enough
    198.             if (instance.triggerSwipeAtMinLength) {
    199.                 return true;
    200.             }
    201.         }
    202.  
    203.         return false;
    204.     }
    205.  
    206.     static bool IsDirection (Vector2 direction, Vector2 cardinalDirection)
    207.     {
    208.         var angle = instance.useEightDirections ? eightDirAngle : fourDirAngle;
    209.         return Vector2.Dot(direction, cardinalDirection) > angle;
    210.     }
    211.  
    212.     static Swipe GetSwipeDirByTouch (Vector2 currentSwipe)
    213.     {
    214.         currentSwipe.Normalize();
    215.         var swipeDir = cardinalDirections.FirstOrDefault(dir => IsDirection(currentSwipe, dir.Value));
    216.         return swipeDir.Key;
    217.     }
    218.  
    219.     static bool IsSwipingDirection (Swipe swipeDir)
    220.     {
    221.         DetectSwipe();
    222.         return swipeDirection == swipeDir;
    223.     }
    224.  
    225.     #endregion
    226. }
    227.  
     

    Attached Files:

    Last edited: Jun 26, 2017
  13. ronybrosh

    ronybrosh

    Joined:
    Dec 9, 2015
    Posts:
    1
    Thanks!!!!
     
  14. herbie

    herbie

    Joined:
    Feb 11, 2012
    Posts:
    237
    Thanks for the code, it's very useful.

    I would like to detect the swipe on a part of the screen. So I think I need a raycast.
    I changed the next part of the code:
    Code (CSharp):
    1.     static bool GetTouchInput ()
    2.     {
    3.         if (Input.touches.Length > 0) {
    4.             Touch t = Input.GetTouch(0);
    5.  
    6.             Ray rayScreenPart = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
    7.             RaycastHit hitScreenPart;
    8.  
    9.             if (t.phase == TouchPhase.Began && screenPart.Raycast(rayScreenPart, out hitScreenPart, Mathf.Infinity)) {
    10.                 firstPressPos = new Vector2(t.position.x, t.position.y);
    11.             }
    12.          
    13.             if (t.phase == TouchPhase.Moved && screenPart.Raycast(rayScreenPart, out hitScreenPart, Mathf.Infinity)) {
    14.                 secondPressPos = new Vector2(t.position.x, t.position.y);
    15.                 return true;
    16.             }
    17.         }
    18.      
    19.         return false;
    20.     }
    21.  
    But it gives the next error: SwipeManager.cs(187,60): error CS0120: An object reference is required to access non-static member `SwipeManager.screenPart'
    Can somebody tell me what I am doing wrong?
     
  15. general_pikachu

    general_pikachu

    Joined:
    Nov 20, 2015
    Posts:
    7
    hello, thank you for you help
    can anyone explain what this line is for
    I'm newbie I didn't get it especially this "dir =>"
    var swipeDir = cardinalDirections.FirstOrDefault(dir => IsDirection(currentSwipe, dir.Value));


     
  16. general_pikachu

    general_pikachu

    Joined:
    Nov 20, 2015
    Posts:
    7
    can anyone add
    -tap
    -double tap
    -long tap
    to this code
     
  17. TheSorcerer

    TheSorcerer

    Joined:
    Dec 30, 2016
    Posts:
    4
    Can someone help me, My player when I swipe down slide's infinitely, there is no problem with jump, only slide, it does not seem to set the boolean in the script and the animator to false when he is sliding
    using UnityEngine;
    using System.Collections;

    public class Movement : MonoBehaviour
    {
    private Rigidbody2D myRigidbody;
    public float moveSpeed;
    public float jumpForce;
    public bool Sliding;
    public bool grounded;
    public LayerMask whatIsGround;
    private Collider2D myCollider;
    private Animator myAnimator;
    Vector2 firstPressPos;
    Vector2 secondPressPos;
    Vector2 currentSwipe;

    // Use this for initialization
    void Start()
    {
    myRigidbody = GetComponent<Rigidbody2D>();
    myCollider = GetComponent<Collider2D>();
    myAnimator = GetComponent<Animator>();
    }
    // Update is called once per frame
    void Update()
    {
    grounded = Physics2D.IsTouchingLayers(myCollider, whatIsGround);
    if (grounded)
    myAnimator.SetFloat("Speed", myRigidbody.velocity.x);
    myAnimator.SetBool("Grounded", grounded);
    {
    myRigidbody.velocity = new Vector2(moveSpeed, myRigidbody.velocity.y);
    }
    if (Input.touches.Length > 0)
    {
    Touch t = Input.GetTouch(0);
    if (t.phase == TouchPhase.Began)
    {
    //save began touch 2d point
    firstPressPos = new Vector2(t.position.x, t.position.y);
    }
    if (t.phase == TouchPhase.Ended)
    {
    //save ended touch 2d point
    secondPressPos = new Vector2(t.position.x, t.position.y);

    //create vector from the two points
    currentSwipe = new Vector3(secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);

    //normalize the 2d vector
    currentSwipe.Normalize();

    //swipe upwards
    if (currentSwipe.y > 0)
    {
    if (grounded)
    myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
    Debug.Log("up swipe");
    }
    //swipe down
    if (currentSwipe.y < 0)
    {
    Sliding = true;
    myAnimator.SetBool("Slide", true);
    Debug.Log("down swipe");
    }
    else if (Sliding && !(currentSwipe.y < 0))
    {
    Sliding = false;
    myAnimator.SetBool("Slide", false);
    }
    }
    }
    }
    }
     
  18. skrpeta

    skrpeta

    Joined:
    Nov 9, 2016
    Posts:
    7
    Thanks for the code, its perfect for my purposes :)
     
  19. dukaric1991

    dukaric1991

    Joined:
    Oct 17, 2016
    Posts:
    1
    Thanks, but how can i implement that the lets say swipe left action is triggered even if my finger is on the screen :)? Like in temple run, because that way its more responsive.
     
  20. BorisS

    BorisS

    Joined:
    Mar 26, 2014
    Posts:
    7
    Hi, dukaric1991. To detect "enough" swype before lifting finger or releasing mouse button, add few lines to these two functions below in BradKeys' code in post #62:

    Code (CSharp):
    1.     static bool GetTouchInput ()
    2.     {
    3.         if (Input.touches.Length > 0) {
    4.             Touch t = Input.GetTouch(0);
    5.  
    6.             if (t.phase == TouchPhase.Began) {
    7.                 firstPressPos = new Vector2(t.position.x, t.position.y);
    8.             }
    9.  
    10.             if (t.phase == TouchPhase.Ended) {
    11.                 secondPressPos = new Vector2(t.position.x, t.position.y);
    12.                 return true;
    13.             }
    14.         }
    15.  
    16.         /////////////////// NEW CODE - BEGIN /////////////////////////
    17.         if (Input.touches.Length > 0) {
    18.             Touch t2 = Input.GetTouch (0);
    19.             if (t2.phase == TouchPhase.Moved) {
    20.                 secondPressPos = new Vector2 (t2.position.x, t2.position.y);
    21.                 Vector2 currentSwipe = new Vector3 (secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
    22.                 float swipeCm = currentSwipe.magnitude / dpcm;
    23.                 print ("Another mobile cycle!");
    24.                 if (swipeCm > instance.minSwipeLength)
    25.                     return true;
    26.             }
    27.         }
    28.         //////////////////////// NEW CODE - END /////////////////////
    29.  
    30.         return false;
    31.     }
    32.  
    33.     static bool GetMouseInput ()
    34.     {
    35.         if (Input.GetMouseButtonDown(0)) {
    36.             firstPressPos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    37.  
    38.         } else if (Input.GetMouseButtonUp(0)) {
    39.             secondPressPos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
    40.             return true;
    41.         }
    42.  
    43.         //////////////////////// NEW CODE - BEGIN ////////////////////
    44.         if (Input.GetMouseButton (0)) {
    45.             secondPressPos = new Vector2 (Input.mousePosition.x, Input.mousePosition.y);
    46.             Vector2 currentSwipe = new Vector3 (secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
    47.             float swipeCm = currentSwipe.magnitude / dpcm;
    48.             print ("Another PC cycle!");
    49.             if (swipeCm > instance.minSwipeLength) return true;
    50.         }
    51.         /////////////////////// NEW CODE - END //////////////////////
    52.  
    53.         return false;
    54.     }
    Works great on my PC and my phones.
     
  21. Reikinfen

    Reikinfen

    Joined:
    Apr 1, 2015
    Posts:
    1

    Hey there!! I have some questions, how would i use this script to throw an object? Like a bubble shooter, but the "cannon" is the player, controled by the accelerometer, that only moves in the X (already working) and the ball should been thrown by the swipe, using its speed and direction. The player is always the initial poimt. No the swipe toutch start point. Got it? Im having a lot of trouble trying to solve this .... Ps. The game is 2d and sorry for my English.
     
  22. rav_al

    rav_al

    Joined:
    Feb 20, 2017
    Posts:
    1
    Thank You so much. I were stuck by 2 weeks.
     
  23. Brad-Keys

    Brad-Keys

    Joined:
    May 1, 2006
    Posts:
    161
    I updated the script just now with two new improvements based on some feedback here.

    @Reikinfen You can now get the swipe velocity and set it as your ball's rigidbody.velocity, or add force to the ball using that velocity. It most likely won't be a speed you like (ie. too slow or too fast) so you'll want to multiply it by a number that makes sense for your game. Here's an example using the new script...

    Code (csharp):
    1.  
    2. public Rigidbody ball;
    3.  
    4. // Modify this number until the speed of the ball feels right
    5. public float speedFactor = 1f;
    6.  
    7. void Start ()
    8. {
    9.     SwipeManager.OnSwipeDetected += OnSwipeDetected;
    10. }
    11.  
    12. void OnSwipeDetected (Swipe direction, Vector2 swipeVelocity)
    13. {
    14.     // Check the ball can be launched, if so, then launch the ball with this code!
    15.     ball.rigidbody.velocity = swipeVelocity * speedFactor;
    16.  
    17.     // Or you can launch it this way instead by adding force
    18.     // ball.rigidbody.AddForce(swipeVelocity * speedFactor);
    19. }
    20.  
    @dukaric1991 I added an inspector option to the script called triggerSwipeAtMinLength. If checked, a swipe is counted when the min swipe length has been reached, even if they didn't lift their finger. Currently a second swipe would not be registered until they do lift their finger. Your use-case could be too specific, so I'm leaving it like that but you're welcome to modify it yourself. You'd basically just make it so that when the swipe ended that way, that end position becomes the new start position of the next swipe. I hope this helps.
     
    khaled24, ow3n and MD_Reptile like this.
  24. LLucile

    LLucile

    Joined:
    Jan 30, 2016
    Posts:
    2
    Hi !

    I have to implement simple gestures too for a smartphone game and found the code here pretty useful. Although, there is a small oversight in the mouse swipe implementation in the last version, I fixed it in the code copy-pasted below. I also used the "swipes too short to be detected" as "single touch" that you can get from the event listener as "Tap".
    I also included a line that you can uncomment to read "taps" in update but I didn't tested it so it might not work exactly as expected...
    It's a bit a "quick and dirty" hack and might need improvements.

    Anyway, thank you very much for all this work, it is being really hepful.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4.  
    5. class CardinalDirection
    6. {
    7.     public static readonly Vector2 Up = new Vector2(0, 1);
    8.     public static readonly Vector2 Down = new Vector2(0, -1);
    9.     public static readonly Vector2 Right = new Vector2(1, 0);
    10.     public static readonly Vector2 Left = new Vector2(-1, 0);
    11.     public static readonly Vector2 UpRight = new Vector2(1, 1);
    12.     public static readonly Vector2 UpLeft = new Vector2(-1, 1);
    13.     public static readonly Vector2 DownRight = new Vector2(1, -1);
    14.     public static readonly Vector2 DownLeft = new Vector2(-1, -1);
    15. }
    16.  
    17. public enum Swipe
    18. {
    19.     None,
    20.     Up,
    21.     Down,
    22.     Left,
    23.     Right,
    24.     UpLeft,
    25.     UpRight,
    26.     DownLeft,
    27.     DownRight,
    28.     Tap
    29. };
    30.  
    31. public class SwipeManager : MonoBehaviour
    32. {
    33.     #region Inspector Variables
    34.  
    35.     [Tooltip("Min swipe distance (inches) to register as swipe")]
    36.     [SerializeField]
    37.     float minSwipeLength = 0.5f;
    38.  
    39.     [Tooltip("If true, a swipe is counted when the min swipe length is reached. If false, a swipe is counted when the touch/click ends.")]
    40.     [SerializeField]
    41.     bool triggerSwipeAtMinLength = false;
    42.  
    43.     [Tooltip("Whether to detect eight or four cardinal directions")]
    44.     [SerializeField]
    45.     bool useEightDirections = false;
    46.  
    47.     #endregion
    48.  
    49.     const float eightDirAngle = 0.906f;
    50.     const float fourDirAngle = 0.5f;
    51.     const float defaultDPI = 72f;
    52.     const float dpcmFactor = 2.54f;
    53.  
    54.     static Dictionary<Swipe, Vector2> cardinalDirections = new Dictionary<Swipe, Vector2>()
    55.     {
    56.         { Swipe.Up,         CardinalDirection.Up                 },
    57.         { Swipe.Down,         CardinalDirection.Down             },
    58.         { Swipe.Right,         CardinalDirection.Right             },
    59.         { Swipe.Left,         CardinalDirection.Left             },
    60.         { Swipe.UpRight,     CardinalDirection.UpRight             },
    61.         { Swipe.UpLeft,     CardinalDirection.UpLeft             },
    62.         { Swipe.DownRight,     CardinalDirection.DownRight         },
    63.         { Swipe.DownLeft,     CardinalDirection.DownLeft         }
    64.     };
    65.  
    66.     public delegate void OnSwipeDetectedHandler(Swipe swipeDirection, Vector2 swipeVelocity);
    67.  
    68.     static OnSwipeDetectedHandler _OnSwipeDetected;
    69.     public static event OnSwipeDetectedHandler OnSwipeDetected
    70.     {
    71.         add
    72.         {
    73.             _OnSwipeDetected += value;
    74.             autoDetectSwipes = true;
    75.         }
    76.         remove
    77.         {
    78.             _OnSwipeDetected -= value;
    79.         }
    80.     }
    81.  
    82.     public static Vector2 swipeVelocity;
    83.  
    84.     static float dpcm;
    85.     static float swipeStartTime;
    86.     static float swipeEndTime;
    87.     static bool autoDetectSwipes;
    88.     static bool swipeEnded;
    89.     static Swipe swipeDirection;
    90.     static Vector2 firstPressPos;
    91.     static Vector2 secondPressPos;
    92.     static SwipeManager instance;
    93.  
    94.  
    95.     void Awake()
    96.     {
    97.         instance = this;
    98.         float dpi = (Screen.dpi == 0) ? defaultDPI : Screen.dpi;
    99.         dpcm = dpi / dpcmFactor;
    100.     }
    101.  
    102.     void Update()
    103.     {
    104.         if (autoDetectSwipes)
    105.         {
    106.             DetectSwipe();
    107.         }
    108.     }
    109.  
    110.     /// <summary>
    111.     /// Attempts to detect the current swipe direction.
    112.     /// Should be called over multiple frames in an Update-like loop.
    113.     /// </summary>
    114.     static void DetectSwipe()
    115.     {
    116.         if (GetTouchInput() || GetMouseInput())
    117.         {
    118.             // Swipe already ended, don't detect until a new swipe has begun
    119.             if (swipeEnded)
    120.             {
    121.                 return;
    122.             }
    123.  
    124.             Vector2 currentSwipe = secondPressPos - firstPressPos;
    125.             float swipeCm = currentSwipe.magnitude / dpcm;
    126.  
    127.             // Check the swipe is long enough to count as a swipe (not a touch, etc)
    128.             if (swipeCm < instance.minSwipeLength)
    129.             {
    130.                 // Swipe was not long enough, abort
    131.                 if (!instance.triggerSwipeAtMinLength)
    132.                 {
    133.                     if (Application.isEditor)
    134.                     {
    135.                         Debug.Log("[SwipeManager] Swipe was not long enough, can be detected as a Tap.");
    136.                     }
    137.                  
    138.                     swipeDirection = Swipe.Tap;
    139.  
    140.                     //trying to send back simple tap
    141.                     if (_OnSwipeDetected != null)
    142.                     {
    143.                         _OnSwipeDetected(swipeDirection, swipeVelocity);
    144.                     }
    145.                 }
    146.  
    147.                 //return;
    148.             }
    149.  
    150.             swipeEndTime = Time.time;
    151.             swipeVelocity = currentSwipe * (swipeEndTime - swipeStartTime);
    152.             swipeDirection = GetSwipeDirByTouch(currentSwipe);
    153.             swipeEnded = true;
    154.  
    155.             if (_OnSwipeDetected != null)
    156.             {
    157.                 _OnSwipeDetected(swipeDirection, swipeVelocity);
    158.             }
    159.         }
    160.         else
    161.         {
    162.             swipeDirection = Swipe.None;
    163.         }
    164.     }
    165.  
    166.     public static bool IsSwipingRight() { return IsSwipingDirection(Swipe.Right); }
    167.     public static bool IsSwipingLeft() { return IsSwipingDirection(Swipe.Left); }
    168.     public static bool IsSwipingUp() { return IsSwipingDirection(Swipe.Up); }
    169.     public static bool IsSwipingDown() { return IsSwipingDirection(Swipe.Down); }
    170.     public static bool IsSwipingDownLeft() { return IsSwipingDirection(Swipe.DownLeft); }
    171.     public static bool IsSwipingDownRight() { return IsSwipingDirection(Swipe.DownRight); }
    172.     public static bool IsSwipingUpLeft() { return IsSwipingDirection(Swipe.UpLeft); }
    173.     public static bool IsSwipingUpRight() { return IsSwipingDirection(Swipe.UpRight); }
    174.     //public static bool IsTapping(){return IsSwipingDirection(Swipe.Tap);}
    175.  
    176.     #region Helper Functions
    177.  
    178.     static bool GetTouchInput()
    179.     {
    180.         if (Input.touches.Length > 0)
    181.         {
    182.             Touch t = Input.GetTouch(0);
    183.  
    184.             // Swipe/Touch started
    185.             if (t.phase == TouchPhase.Began)
    186.             {
    187.                 firstPressPos = t.position;
    188.                 swipeStartTime = Time.time;
    189.                 swipeEnded = false;
    190.                 // Swipe/Touch ended
    191.             }
    192.             else if (t.phase == TouchPhase.Ended)
    193.             {
    194.                 secondPressPos = t.position;
    195.                 return true;
    196.                 // Still swiping/touching
    197.             }
    198.             else
    199.             {
    200.                 // Could count as a swipe if length is long enough
    201.                 if (instance.triggerSwipeAtMinLength)
    202.                 {
    203.                     return true;
    204.                 }
    205.             }
    206.         }
    207.  
    208.         return false;
    209.     }
    210.  
    211.     static bool GetMouseInput()
    212.     {
    213.         // Swipe/Click started
    214.         if (Input.GetMouseButtonDown(0))
    215.         {
    216.             firstPressPos = (Vector2)Input.mousePosition;
    217.             swipeStartTime = Time.time;
    218.             swipeEnded = false;
    219.             // Swipe/Click ended
    220.         }
    221.         else if (Input.GetMouseButtonUp(0))
    222.         {
    223.             secondPressPos = (Vector2)Input.mousePosition;
    224.             return true;
    225.             // Still swiping/clicking
    226.         }
    227.         else
    228.         {
    229.             // Could count as a swipe if length is long enough
    230.             if (instance.triggerSwipeAtMinLength)
    231.             {
    232.                 return true;
    233.             }
    234.         }
    235.  
    236.         return false;
    237.     }
    238.  
    239.     static bool IsDirection(Vector2 direction, Vector2 cardinalDirection)
    240.     {
    241.         var angle = instance.useEightDirections ? eightDirAngle : fourDirAngle;
    242.         return Vector2.Dot(direction, cardinalDirection) > angle;
    243.     }
    244.  
    245.     static Swipe GetSwipeDirByTouch(Vector2 currentSwipe)
    246.     {
    247.         currentSwipe.Normalize();
    248.         var swipeDir = cardinalDirections.FirstOrDefault(dir => IsDirection(currentSwipe, dir.Value));
    249.         return swipeDir.Key;
    250.     }
    251.  
    252.     static bool IsSwipingDirection(Swipe swipeDir)
    253.     {
    254.         DetectSwipe();
    255.         return swipeDirection == swipeDir;
    256.     }
    257.  
    258.     #endregion
    259. }
     
    Last edited: Mar 16, 2017
  25. Betraydabear

    Betraydabear

    Joined:
    Mar 9, 2017
    Posts:
    1
    I copy Edmosis13 code for the mouse swipe, i attached the script to my character, but it won't move at all. however, im getting all the debug message. please help.
     

    Attached Files:

    • code.png
      code.png
      File size:
      51.8 KB
      Views:
      674
  26. LLucile

    LLucile

    Joined:
    Jan 30, 2016
    Posts:
    2
    The script here won't make your character move. You have to use the functions and events it implements into your own character controller script.
     
  27. jdxinteractive

    jdxinteractive

    Joined:
    Mar 16, 2017
    Posts:
    3
    Help! I'm a newbie to Unity. I've attached this script to my GameObject, and used the "Checking via event" method. But it only captures the swipe direction 1 time. I can't get it to detect swipes after that initial event. I've tried attaching it to the specific sprite that I want to swipe. I've tried attaching it to an empty GameObject and nothing seems to work. Please help!



     
  28. ronaldrerosa

    ronaldrerosa

    Joined:
    Sep 25, 2014
    Posts:
    1

    hi @Brad-Keys... Im trying to implement the updated version of your swipe code.. the only problem is that it only iexecutes ones.. it logs the first swipe but doesn't log the following swipes after that.. am I missing something?
     
  29. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    364
    There is a line missing in GetMouseInput, check #74 reply
     
  30. dilmer

    dilmer

    Joined:
    Jun 15, 2013
    Posts:
    225
    Guys this worked right away thank you!

    Question, I am writing an Isometric style game and instead of swiping straight down, up, left or right, I would like to allow the user to swipe down in an angle, same with all other directions.

    Let me know if this something one of you did already.

    Thanks

    Edit this:

    I found the answer here:
    https://sushanta1991.blogspot.com/2014/05/simple-swipe-in-unity-using-angle.html
     
  31. esd1989

    esd1989

    Joined:
    Apr 21, 2014
    Posts:
    3
    Hey, I appreciate the sharing of your script, time, and effort. I've written similar in the past, but haven't updated my old work in a long time. I wanted to note that without resetting the swipeEnded when using the GetMouseInput(), a user cannot detect multiple swipes with the mouse (I'm testing swipes with my mouse, but I guess it won't matter as much for most users as they don't plan to swipe with their mouse).

    Just wanted to put the note in here.

    Once again, it looks good and I appreciate it.

    Best,