# Swipe in all directions Touch and Mouse

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

1. ### ickydime

Joined:
Nov 20, 2012
Posts:
54

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

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

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.
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.
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>();
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.         {
53.         }
54.         // Uncomment if you want it only to allow mouse swipes in the Unity Editor
55.         //#endif
56.
58.     }
59. }
60.
61.

Code (CSharp):
1. using UnityEngine;
2. using System.Reflection;
3. using System.Collections.Generic;
4.
5. /// <summary>
6. /// Touch creator.
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.         {
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

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

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

6. ### 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

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

Joined:
Oct 24, 2012
Posts:
349

thanks soo much !

9. ### kaye17

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

10. ### 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.
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

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.

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)
- 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.     {
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:

• ###### SwipeManager.cs
File size:
7.3 KB
Views:
2,092
Last edited: Jun 26, 2017

Joined:
Dec 9, 2015
Posts:
1
Thanks!!!!

14. ### 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

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));

Joined:
Nov 20, 2015
Posts:
7
-tap
-double tap
-long tap
to this code

17. ### 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;
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

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

19. ### 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

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

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

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

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
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

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.     {
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

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.

File size:
51.8 KB
Views:
674
26. ### 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

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

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

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

30. ### 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:

https://sushanta1991.blogspot.com/2014/05/simple-swipe-in-unity-using-angle.html

31. ### 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,