SwipeManager.cs 5.9 KB

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