Pages

Gin Rummy Indian Rummy Nine Men's Morris and more Air Attack

Tuesday 10 February 2015

Detecting swipe from Unity3D c# scripts


Let me share a simple code to detect swipe from Unity 3D application. The sample code is written in c#, but it can easily be ported to other languages.

Please find the code below, I guess the code is documented enough to understand.

This implementation detects swipe using angle of swipe from X and Y axis.



using UnityEngine;
using System.Collections;

public class SwipeDetector : MonoBehaviour {

    private const int mMessageWidth  = 200;
    private const int mMessageHeight = 64;

    private readonly Vector2 mXAxis = new Vector2(1, 0);
    private readonly Vector2 mYAxis = new Vector2(0, 1);

    private readonly string [] mMessage = {
        "",
        "Swipe Left",
        "Swipe Right",
        "Swipe Top",
        "Swipe Bottom"
    };

    private int mMessageIndex = 0;

    // The angle range for detecting swipe
    private const float mAngleRange = 30;

    // To recognize as swipe user should at lease swipe for this many pixels
    private const float mMinSwipeDist = 50.0f;

    // To recognize as a swipe the velocity of the swipe
    // should be at least mMinVelocity
    // Reduce or increase to control the swipe speed
    private const float mMinVelocity  = 2000.0f;

    private Vector2 mStartPosition;
    private float mSwipeStartTime;

    // Use this for initialization
    void Start () {
    }
    
    // Update is called once per frame
    void Update () {

        // Mouse button down, possible chance for a swipe
        if (Input.GetMouseButtonDown(0)) {
            // Record start time and position
            mStartPosition = new Vector2(Input.mousePosition.x,
                                         Input.mousePosition.y);
            mSwipeStartTime = Time.time;
        }

        // Mouse button up, possible chance for a swipe
        if (Input.GetMouseButtonUp(0)) {
            float deltaTime = Time.time - mSwipeStartTime;

            Vector2 endPosition  = new Vector2(Input.mousePosition.x,
                                               Input.mousePosition.y);
            Vector2 swipeVector = endPosition - mStartPosition;

            float velocity = swipeVector.magnitude/deltaTime;

            if (velocity > mMinVelocity &&
                swipeVector.magnitude > mMinSwipeDist) {
                // if the swipe has enough velocity and enough distance

                swipeVector.Normalize();

                float angleOfSwipe = Vector2.Dot(swipeVector, mXAxis);
                angleOfSwipe = Mathf.Acos(angleOfSwipe) * Mathf.Rad2Deg;

                // Detect left and right swipe
                if (angleOfSwipe < mAngleRange) {
                    OnSwipeRight();
                } else if ((180.0f - angleOfSwipe) < mAngleRange) {
                    OnSwipeLeft();
                } else {
                    // Detect top and bottom swipe
                    angleOfSwipe = Vector2.Dot(swipeVector, mYAxis);
                    angleOfSwipe = Mathf.Acos(angleOfSwipe) * Mathf.Rad2Deg;
                    if (angleOfSwipe < mAngleRange) {
                        OnSwipeTop();
                    } else if ((180.0f - angleOfSwipe) < mAngleRange) {
                        OnSwipeBottom();
                    } else {
                        mMessageIndex = 0;
                    }
                }
            }
        }
    }

    void OnGUI() {
        // Display the appropriate message
        GUI.Label(new Rect((Screen.width-mMessageWidth)/2,
                           (Screen.height-mMessageHeight)/2,
                            mMessageWidth, mMessageHeight),
                  mMessage[mMessageIndex]);
    }

    private void OnSwipeLeft() {
        mMessageIndex = 1;
    }

    private void OnSwipeRight() {
        mMessageIndex = 2;
    }

    private void OnSwipeTop() {
        mMessageIndex = 3;
    }

    private void OnSwipeBottom() {
        mMessageIndex = 4;
    }
}

10 comments:

  1. hey bro.. thanx alot.. you are amazing...

    ReplyDelete
    Replies
    1. Howdy Mate,

      Grazie! Grazie! Grazie! Your blog is indeed quite interesting around Detecting swipe from Unity3D c# scripts! I agree with you on lot of points!

      A subset of a natural language contains these sentences:
      1) Triangle ABC.
      2) Line Segment AB.
      3) Angle A.
      In this set, names of triangles are formed by putting three letters together,
      all drawn from the alphabet {A,B,C,D,E}. Line segment names are defined by
      putting two letters together from the previous alphabet. And angle names are
      (suprise!) given by any letter in that alphabet.

      A type cast should not be used to override a const or volatile declaration. Overriding these type modifiers can cause the program to fail to run correctly. A type cast should not be used to turn a pointer to one type of structure or data type into another. In the rare events in which this action is beneficial, using a union to hold the values makes the programmer’s intentions clearer.

      Great effort, I wish I saw it earlier. Would have saved my day:)

      Thank you,
      Jim

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Great. But I am using Input.GetAxis("Mouse X") and similarly Y axis. This way you can detect swipe and also manage speed of swipe. Thanks for nice post.

    ReplyDelete
  4. This saved me a ton of time. Thank you so much for sharing this with the community!

    ReplyDelete
  5. Thank you very much! It really helped me, saving a lot o time :)

    ReplyDelete
  6. I am new to unity3d, please tell me how to connect this script to a GameObject(Eg. A Ball),so that i can move the gameobject through swipe and please tell whether this script work with Samsung GearVR.

    ReplyDelete
    Replies
    1. You can drag and drop the script onto the game object to attach it.
      I have not verified the script on Samsung gear.

      Delete
  7. thanx for sharing i make htc vive version from this code https://github.com/omerfaruk/htc-vive-swipe

    ReplyDelete