how to differentiate touch and swipe
in my game my player is moving with 5 controllers. swipe 4 directions and touch........... am getting confused with touch and swipe...
can any one suggest me how to do it...
Answer by sHajir · Feb 09, 2017 at 02:05 AM
Hi, did you find out how to differentiate a touch and a swipe ? I'm having the same problem. i tried to solve it via
-TouchPhase.Began (get current position)
-TouchPhase.Moved (check current position with position from began ->if difference is big then it is a swipe and no tap )
-TouchPhase.Ended (check current position with position from began ->if difference too is small then it is a tap and no swipe)
My Problem: tap is recognized too late, when my finger leaves the screen. This is because of TouchPhase.Ended. I'm looking for another solution.
Answer by thestrandedmoose · Feb 23, 2019 at 06:32 PM
Hey guys- not sure if you solved this but I ran into this problem a day ago as well. Figure I'd leave a solution here as well in case anyone needs it in the future. I ended up solving this with the following steps: 1. on Input.touches[0].phase == TouchPhase.Began I set a private bool tapRequested to true 2. Create a Vector2 called SwipeDelta to check the magnitude of each swipe. If the magnitude is a certain distance, say 100, set tapRequested to false and set swipeRight, swipeLeft, etc to true 3. When touchphase ends, check if tapRequested is still true. If so, it was a swipe and not a tap. That means the player made either a very small swipe, or tap. You'll have to adjust the number "100" to whatever sensitivity setting feels best for you.
Here is the tutorial I started with and my final code modified to fit my needs: YouTube Tutorial
public class Swipe : MonoBehaviour
{
private bool tap, swipeLeft, swipeRight, swipeUp, swipeDown;
private bool tapRequested;
private bool isDragging = false;
private Vector2 startTouch, swipeDelta;
private void Update()
{
tap = swipeLeft = swipeRight = swipeUp = swipeDown = false;
#region Standalone Inputs
if (Input.GetMouseButtonDown(0))
{
tapRequested = true;
isDragging = true;
startTouch = Input.mousePosition;
}
else if (Input.GetMouseButtonUp(0))
{
if (tapRequested) { tap = true;}
isDragging = false;
Reset();
}
#endregion
#region Mobile Inputs
if(Input.touchCount > 0)
{
if(Input.touches[0].phase == TouchPhase.Began)
{
tapRequested = true;
isDragging = true;
startTouch = Input.touches[0].position;
}
else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled)
{
if (tapRequested) { tap = true; }
isDragging = false;
Reset();
}
}
#endregion
//Calculate the distance
swipeDelta = Vector2.zero;
if (isDragging)
{
if(Input.touchCount > 0) { swipeDelta = Input.touches[0].position - startTouch; }
else if (Input.GetMouseButton(0)) { swipeDelta = (Vector2)Input.mousePosition - startTouch; }
}
//Did we cross the dead zone?
if(swipeDelta.magnitude > 100)
{
tapRequested = false;
//Which direction are we swiping?
float x = swipeDelta.x;
float y = swipeDelta.y;
if(Mathf.Abs(x) > Mathf.Abs(y))
{
//Left or right?
if (x > 0) { swipeRight = true; }
else { swipeLeft = true; }
//x > 0 ? swipeRight = true : swipeLeft = true;
}
else
{
//Up or down?
if (y > 0) { swipeUp = true; }
else { swipeDown = true; }
// y > 0 ? swipeUp = true : swipeDown = true;
}
Reset();
}
}
private void Reset()
{
startTouch = swipeDelta = Vector2.zero;
isDragging = false;
}
public Vector2 SwipeDelta { get { return swipeDelta; } }
public bool SwipeLeft { get { return swipeLeft; } }
public bool SwipeRight { get { return swipeRight; } }
public bool SwipeUp { get { return swipeUp; } }
public bool SwipeDown { get { return swipeDown; } }
public bool Tap { get { return tap; } }
}
If anyone is still looking for this, for me the same script worked except I had to add tapRequested = false; to the very end. Also I have some $$anonymous$$or differences that were recommended in the videos comment section if anyone is wondering.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Swipe$$anonymous$$anager : $$anonymous$$onoBehaviour {
public static bool tap, swipeLeft, swipeRight, swipeUp, swipeDown;
private bool tapRequested;
private bool isDraging = false;
private Vector2 startTouch, swipeDelta;
private void Update() {
if(Time.timeScale == 1) {
tap = swipeDown = swipeUp = swipeLeft = swipeRight = false;
if (Input.Get$$anonymous$$ouseButtonDown(0)) {
tapRequested = true;
isDraging = true;
startTouch = Input.mousePosition;
} else if (Input.Get$$anonymous$$ouseButtonUp(0)) {
if(tapRequested)
tap = true;
isDraging = false;
Reset();
}
if (Input.touches.Length > 0) {
if (Input.touches[0].phase == TouchPhase.Began) {
tapRequested = true;
isDraging = true;
startTouch = Input.touches[0].position;
} else if (Input.touches[0].phase == TouchPhase.Ended || Input.touches[0].phase == TouchPhase.Canceled) {
if (tapRequested) { tap = true; }
isDraging = false;
Reset();
}
}
//Calculate the distance
swipeDelta = Vector2.zero;
if (isDraging) {
if (Input.touches.Length < 0)
swipeDelta = Input.touches[0].position - startTouch;
else if (Input.Get$$anonymous$$ouseButton(0))
swipeDelta = (Vector2)Input.mousePosition - startTouch;
}
//Did we cross the distance?
if (swipeDelta.magnitude > 100) {
float x = swipeDelta.x;
float y = swipeDelta.y;
if ($$anonymous$$athf.Abs(x) > $$anonymous$$athf.Abs(y)) {
if (x < 0)
swipeLeft = true;
else
swipeRight = true;
} else {
if (y < 0)
swipeDown = true;
else
swipeUp = true;
}
Reset();
}
}
}
private void Reset() {
startTouch = swipeDelta = Vector2.zero;
isDraging = false;
tapRequested = false;
}
}
Your answer
Follow this Question
Related Questions
Problem with Swipe and rb.MovePosition 0 Answers
DragMouseOrbit for touch screen?? 0 Answers
Disable Input.getTouch in full screen 0 Answers
Touch Controls inaccurate after screen sleeping 0 Answers
Replace touch movement! 0 Answers