Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect swipe gesture direction

Tags:

c#

unity3d

That is my code to try and simulate a swipe gesture so when I build to mobile I know it will work. Nothing is being logged and I am confused on why it seems to not work. I want it to print out in the console that I either swiped RTL (Right to Left) or LTR (Left to right). I do not see what I am doing wrong.

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        startPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    }
    if (Input.GetMouseButtonUp(0))
    {
        endPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    }

    if (startPosition != endPosition && startPosition != Vector3.zero && endPosition != Vector3.zero)
    {
        float deltaX = endPosition.x - startPosition.x;
        float deltaY = endPosition.y - startPosition.y;
        if ((deltaX > 5.0f || deltaX < -5.0f) && (deltaY >= -1.0f || deltaY <= 1.0f))
        {
            if (startPosition.x < endPosition.x)
            {
                print("LTR");
            }
            else
            {
                print("RTL");
            }
        }
        startPosition = endPosition = Vector3.zero;
    }
}
like image 578
Cory Sparks Avatar asked Jan 05 '17 18:01

Cory Sparks


People also ask

How do I use swipe gesture recognizer in Swift?

A swipe gesture recognizer detects swipes in one of four directions, up , down , left , and right . We set the direction property of the swipe gesture recognizer to down . If the user swipes from the top of the blue view to the bottom of the blue view, the swipe gesture recognizer invokes the didSwipe(_:)

What is swipe gesture on iPhone?

Swipe right or left along the bottom edge of the screen to quickly switch between open apps. See Switch between open apps on iPhone.


2 Answers

I can spot some few problems in your code. It's not a good idea to compare Vector3 with == or !=. Approximate comparison is fine. You are using Input.GetMouseButtonDown on a mobile platform.

You need to use Input.touches to do this. Loop over it, store the beginning position in TouchPhase.Began and then the end position in TouchPhase.Ended. You can then use both variables to figure it which direction the finger went.

The code below detects swipe direction even when the finger is not yet released with the help of TouchPhase.Moved. You can disable that by enabling the detectSwipeOnlyAfterRelease boolean variable. You can also modify SWIPE_THRESHOLD for sensitivity.

public class SwipeDetector : MonoBehaviour
{
    private Vector2 fingerDown;
    private Vector2 fingerUp;
    public bool detectSwipeOnlyAfterRelease = false;

    public float SWIPE_THRESHOLD = 20f;

    // Update is called once per frame
    void Update()
    {

        foreach (Touch touch in Input.touches)
        {
            if (touch.phase == TouchPhase.Began)
            {
                fingerUp = touch.position;
                fingerDown = touch.position;
            }

            //Detects Swipe while finger is still moving
            if (touch.phase == TouchPhase.Moved)
            {
                if (!detectSwipeOnlyAfterRelease)
                {
                    fingerDown = touch.position;
                    checkSwipe();
                }
            }

            //Detects swipe after finger is released
            if (touch.phase == TouchPhase.Ended)
            {
                fingerDown = touch.position;
                checkSwipe();
            }
        }
    }

    void checkSwipe()
    {
        //Check if Vertical swipe
        if (verticalMove() > SWIPE_THRESHOLD && verticalMove() > horizontalValMove())
        {
            //Debug.Log("Vertical");
            if (fingerDown.y - fingerUp.y > 0)//up swipe
            {
                OnSwipeUp();
            }
            else if (fingerDown.y - fingerUp.y < 0)//Down swipe
            {
                OnSwipeDown();
            }
            fingerUp = fingerDown;
        }

        //Check if Horizontal swipe
        else if (horizontalValMove() > SWIPE_THRESHOLD && horizontalValMove() > verticalMove())
        {
            //Debug.Log("Horizontal");
            if (fingerDown.x - fingerUp.x > 0)//Right swipe
            {
                OnSwipeRight();
            }
            else if (fingerDown.x - fingerUp.x < 0)//Left swipe
            {
                OnSwipeLeft();
            }
            fingerUp = fingerDown;
        }

        //No Movement at-all
        else
        {
            //Debug.Log("No Swipe!");
        }
    }

    float verticalMove()
    {
        return Mathf.Abs(fingerDown.y - fingerUp.y);
    }

    float horizontalValMove()
    {
        return Mathf.Abs(fingerDown.x - fingerUp.x);
    }

    //////////////////////////////////CALLBACK FUNCTIONS/////////////////////////////
    void OnSwipeUp()
    {
        Debug.Log("Swipe UP");
    }

    void OnSwipeDown()
    {
        Debug.Log("Swipe Down");
    }

    void OnSwipeLeft()
    {
        Debug.Log("Swipe Left");
    }

    void OnSwipeRight()
    {
        Debug.Log("Swipe Right");
    }
}
like image 127
Programmer Avatar answered Sep 20 '22 01:09

Programmer


Thanks to Programmer, I used his suggestion and wrote a small component which works both with mouse and touch. The mouse will allow you to debug app on PC. I also added time threshold in seconds, since swipe cannot be too long.

using System;
using UnityEngine;
using UnityEngine.Events;

public class SwipeManager : MonoBehaviour {

  public float swipeThreshold = 50f;
  public float timeThreshold = 0.3f;

  public UnityEvent OnSwipeLeft;
  public UnityEvent OnSwipeRight;
  public UnityEvent OnSwipeUp;
  public UnityEvent OnSwipeDown;

  private Vector2 fingerDown;
  private DateTime fingerDownTime;
  private Vector2 fingerUp;
  private DateTime fingerUpTime;

  private void Update () {
    if (Input.GetMouseButtonDown(0)) {
      this.fingerDown = Input.mousePosition;
      this.fingerUp = Input.mousePosition;
      this.fingerDownTime = DateTime.Now;
    }
    if (Input.GetMouseButtonUp(0)) {
      this.fingerDown = Input.mousePosition;
      this.fingerUpTime = DateTime.Now;
      this.CheckSwipe();
    }
    foreach (Touch touch in Input.touches) {
      if (touch.phase == TouchPhase.Began) {
        this.fingerDown = touch.position;
        this.fingerUp = touch.position;
        this.fingerDownTime = DateTime.Now;
      }
      if (touch.phase == TouchPhase.Ended) {
        this.fingerDown = touch.position;
        this.fingerUpTime = DateTime.Now;
        this.CheckSwipe();
      }
    }
  }

  private void CheckSwipe() {
    float duration = (float)this.fingerUpTime.Subtract(this.fingerDownTime).TotalSeconds;
    if (duration > this.timeThreshold) return;

    float deltaX = this.fingerDown.x - this.fingerUp.x;
    if (Mathf.Abs(deltaX) > this.swipeThreshold) {
      if (deltaX > 0) {
        this.OnSwipeRight.Invoke();
        //Debug.Log("right");
      } else if (deltaX < 0) {
        this.OnSwipeLeft.Invoke();
        //Debug.Log("left");
      }
    }

    float deltaY = fingerDown.y - fingerUp.y;
    if (Mathf.Abs(deltaY) > this.swipeThreshold) {
      if (deltaY > 0) {
        this.OnSwipeUp.Invoke();
        //Debug.Log("up");
      } else if (deltaY < 0) {
        this.OnSwipeDown.Invoke();
        //Debug.Log("down");
      }
    }

    this.fingerUp = this.fingerDown;
  }
}
like image 41
Developer Avatar answered Sep 18 '22 01:09

Developer