Swipe help please

I have looked and looked for examples and it would be great if someone would be able to just make a small script to show how to do this.

I would like to know how to detect swipes, left right up and down if possible. I have noticed people seem reluctant to show any code (I have no idea why) and the scripts I can find are a bit over the top it seems.

I wrote this a few weeks ago

http://forum.unity3d.com/viewtopic.php?t=47495

1 Like

sigh Why is the JS source of swipe code so elusive? We are developing for iPhone are we not? Can anyone from Unity help. I appreciate the C# versions, but no idea how to implement them into my app that is all JS (and all that I know in limited programming skills).

Swipe left > do something
Swipe right > do something

Thats all i need to figure out.

The only thing Iā€™ve found in JS so far that works is this (sorry canā€™t find the Unity forum link for it to credit it:

var smoothingConstant = .01; // Speed of ending-swipe 

//private var layerMask = 1 << 11; // Only check for collisions in TouchManager layer 
private var hit : RaycastHit; // Hit variable 
private var joystickId : int; // Stores which finger is on the joystick 
private var previousTouch : iPhoneTouch; // Stores the previous touch 
private var endedTouch = false; // Informs when the touch has ended 

private var velocity : float; // Velocity 
private var time : float; // Time 
private var acceleration : float; // Acceleration 



var test : GameObject;

function Update () { 
    for (var touch : iPhoneTouch in iPhoneInput.touches) { 
       // Draw a ray from the camera to the touch position 
       var ray : Ray = Camera.main.ScreenPointToRay (touch.position); 
       // If the touch is new, and it is on the joystick, then store the touch in joystickId 
       if (touch.phase == iPhoneTouchPhase.Began  touch.position.x < 150) { 
          joystickId = touch.fingerId; 
          
     } 
       // If the finger is not on the joystick, check to see if it hits the "able to swipe" area. If so, then call the swipe function 
       // Note -- the collision is a box, with rendering removed in layer 11. It is the child of the parent, and is the appropriate size. 
        if (touch.phase != iPhoneTouchPhase.Ended  touch.phase == iPhoneTouchPhase.Moved) { 
        // if (Physics.Raycast (ray, hit, layerMask)) { 
            if (endedTouch) 
               previousTouch = touch; 
             
            Swipe(touch); 
            previousTouch = touch; 
            endedTouch = false; 
            Instantiate(test);
            
            
         
       } 
       // If the finger doing the swipe has been removed, then reset all the variables 
       else if (touch.phase == iPhoneTouchPhase.Ended) { 
          endedTouch = true; 
          velocity = 0; 
          time = 0; 
          
       } 
       // If the touch ended, smooth it out 
       if (endedTouch == true) { 
          if ( velocity != 0) 
             SmoothEnding();    
      } 
       
   } 
} 

// Swipe function 
function Swipe ( touch : iPhoneTouch ) { 
   // Temporary variables 
   var deltaTouch : float = (touch.position.x - previousTouch.position.x); 
   var initialTime = time; 
   var initialVelocity = deltaTouch/(time); 
    
   // Stored variables 
   time += Time.deltaTime; 
   velocity = deltaTouch/(time); 
   acceleration = (velocity - initialVelocity)/(time - initialTime); 
    
   // Transform the position with respect to acceleration 
   //transform.Rotate(0, -deltaTouch * Time.deltaTime, 0); 
   transform.Rotate(0, velocity * Time.deltaTime, 0); 
   Debug.Log("Acceleration =" + acceleration + " and Velocity = " + velocity); 
}

HOWEVER, I canā€™t for the life of me figure out how to change/add to this code to detect swipe direction.

Any help greatly appreciatedā€¦ Iā€™ve been hogging these forums tonight with this issue hoping to find some assistance somewhere!

The basic routine is:-

  • On the touch start phase, record the position and the time and set a boolean value to say that a swipe might be happening.

  • Each frame during the drag phase, check that the finger doesnā€™t stray too far from a straight line (horizontal or vertical, depending on the swipe type). If it does stray, cancel the boolean flag to denote it isnā€™t a swipe.

  • On the end phase, again, record the time and position and subtract the initial time and position. If the time is greater than the maximum swipe time or the distance is less than the minimum swipe distance, or the boolean flag is false then itā€™s not a swipe. Otherwise, it is.

Annoyingly, I canā€™t test the following code on a device at the moment, but it should at least give you an idea. This is for a vertical swipe, but you can get a horizontal swipe by changing touch.position.y for touch.position.x, etc.

var startTime: float;
var startPos: Vector2;
var couldBeSwipe: boolean;
var comfortZone: float;
var minSwipeDist: float;
var maxSwipeTime: float;


function Update() {
	if (iPhoneInput.touchCount > 0) {
		var touch = iPhoneInput.touches[0];
		
		switch (touch.phase) {
			case iPhoneTouchPhase.Began:
				couldBeSwipe = true;
				startPos = touch.position;
				startTime = Time.time;
				break;
			
			case iPhoneTouchPhase.Moved:
				if (Mathf.Abs(touch.position.y - startPos.y) > comfortZone) {
					couldBeSwipe = false;
				}
				break;
			
			case iPhoneTouchPhase.Stationary:
				couldBeSwipe = false;
				break;
			
			case iPhoneTouchPhase.Ended:
				var swipeTime = Time.time - startTime;
				var swipeDist = (touch.position - startPos).magnitude;
				
				if (couldBeSwipe  (swipeTime < maxSwipeTime)  (swipeDist > minSwipeDist)) {
					// It's a swiiiiiiiiiiiipe!
					var swipeDirection = Mathf.Sign(touch.position.y - startPos.y);
					
					// Do something here in reaction to the swipe.
				}
				break;
		}
	}
}
4 Likes

Thanks for this.

This script looks a lot cleaner than the one Iā€™ve ā€˜hackedā€™ together to get things working.

Iā€™ll take a lookā€¦ Thanks for your help :slight_smile:

So this swipe detection is great, but how do I move an object based upon the distance and direction of the swipe? I need to move a camera (in any direction, its a top down 2d game) based upon the length and direction of the swipe. Then it should slow down, then stop moving. The camera should also move while the finger is dragging. Any thoughts?

Not exactly what youā€™re trying to do but might get you started in that direction:

http://forum.unity3d.com/viewtopic.php?t=16159

Also not exactly what youā€™re looking for, but similar: SwipeControl (GameAssets.net)

SWIPE WITH TOUCHā€¦THIS REALLY WORKSā€¦ TRY IT

///////////////////////////////////////////////
code:-
/////////////////////////////////////////////
using UnityEngine;
using System.Collections;

public class Touch
{
public iPhoneTouch touch1;
public Vector2 Start_pos;
public float time1;

}

public class swipe : MonoBehaviour {

ArrayList ar=new ArrayList();
float x_dir,y_dir;
// Use this for initialization
void Start () {

}
Vector2 end_pos,start_pos;
GameObject txt;
TextMesh tm;
// Update is called once per frame
void Update () {

txt=GameObject.Find(ā€œNew Textā€);

//tm=txt.GetComponent(typeof(TextMesh)) as TextMesh;

//txt.transform.position=pos;

GameObject c=GameObject.Find(ā€œCubeā€);
foreach(iPhoneTouch touch in iPhoneInput.touches)
{

if(touch.phase==iPhoneTouchPhase.Began)

{
Vector2 temp=camera.WorldToScreenPoint(c.transform.position);

Vector2 t=touch.position;

if(temp.x+25>t.x temp.x-25<t.x)
{

if(temp.y+25>t.y temp.y-25<t.y )
{

Touch ob =new Touch();
ob.time1=(float)Time.time;
ob.touch1=touch;
ob.Start_pos=t;
ar.Add(ob);
}

}

}

if(touch.phase==iPhoneTouchPhase.Ended)
{
for(int i=0;i<ar.Count;i++)
{

Touch ob=(Touch)ar*;*

  • if(ob.touch1.fingerId==touch.fingerId)*

  • {*

  • float time_end=(float)Time.time;*

  • if((time_end-ob.time1)<1)*

  • {*

  • end_pos=touch.position;*

/*if(end_pos.x>ob.Start_pos.x)

  • {*

  • x_dir=(end_pos.x-(end_pos.x-ob.Start_pos.x));*

  • }*

  • else*

  • {*

  • x_dir=ob.Start_pos.x-(ob.Start_pos.x-end_pos.x);*

  • }*

  • if(end_pos.y>ob.Start_pos.y)*

  • { y_dir=end_pos.y-(end_pos.y-ob.Start_pos.y);*

  • }*

  • else*

  • {*

  • y_dir=ob.Start_pos.y-(ob.Start_pos.y-end_pos.y);*
    _ }*/_
    // float dir=Mathf.Atan2((end_pos.y-ob.Start_pos.y),(end_pos.x-ob.Start_pos.x));
    c.rigidbody.AddForce((end_pos.x-ob.Start_pos.x)*10,(end_pos.y-ob.Start_pos.y)*10,0);

  • //tm.text=iPhoneInput.touchCount);*

  • ar.RemoveAt(i);*

  • }}*

  • }*

  • }*

  • }*

  • }*
    //
    //void t1(iPhoneTouch t2)
    //
    //{
    *// *
    //if(t2.phase==iPhoneTouchPhase.)
    //{
    *// *
    *// *
    *// *
    *// *
    *// } *
    *// *
    // }
    }

//////////////////////////////////
SWIPE WITH TOUCH

//////////////////////////////////

using UnityEngine;
using System.Collections;

public class Touch
{
public iPhoneTouch touch1;
public Vector2 Start_pos;
public float time1;

}

public class swipe : MonoBehaviour {

ArrayList ar=new ArrayList();
float x_dir,y_dir;
// Use this for initialization
void Start () {

}
Vector2 end_pos,start_pos;
GameObject txt;
TextMesh tm;
// Update is called once per frame
void Update () {

txt=GameObject.Find(ā€œNew Textā€);

//tm=txt.GetComponent(typeof(TextMesh)) as TextMesh;

//txt.transform.position=pos;

GameObject c=GameObject.Find(ā€œCubeā€);
foreach(iPhoneTouch touch in iPhoneInput.touches)
{

if(touch.phase==iPhoneTouchPhase.Began)

{
Vector2 temp=camera.WorldToScreenPoint(c.transform.position);

Vector2 t=touch.position;

if(temp.x+25>t.x temp.x-25<t.x)
{

if(temp.y+25>t.y temp.y-25<t.y )
{

Touch ob =new Touch();
ob.time1=(float)Time.time;
ob.touch1=touch;
ob.Start_pos=t;
ar.Add(ob);
}

}

}

if(touch.phase==iPhoneTouchPhase.Ended)
{
for(int i=0;i<ar.Count;i++)
{

Touch ob=(Touch)ar*;*

  • if(ob.touch1.fingerId==touch.fingerId)*

  • {*

  • float time_end=(float)Time.time;*

  • if((time_end-ob.time1)<1)*

  • {*

  • end_pos=touch.position;*

/*if(end_pos.x>ob.Start_pos.x)

  • {*

  • x_dir=(end_pos.x-(end_pos.x-ob.Start_pos.x));*

  • }*

  • else*

  • {*

  • x_dir=ob.Start_pos.x-(ob.Start_pos.x-end_pos.x);*

  • }*

  • if(end_pos.y>ob.Start_pos.y)*

  • { y_dir=end_pos.y-(end_pos.y-ob.Start_pos.y);*

  • }*

  • else*

  • {*

  • y_dir=ob.Start_pos.y-(ob.Start_pos.y-end_pos.y);*
    _ }*/_
    // float dir=Mathf.Atan2((end_pos.y-ob.Start_pos.y),(end_pos.x-ob.Start_pos.x));
    c.rigidbody.AddForce((end_pos.x-ob.Start_pos.x)*10,(end_pos.y-ob.Start_pos.y)*10,0);

  • //tm.text=iPhoneInput.touchCount);*

  • ar.RemoveAt(i);*

  • }}*

  • }*

  • }*

  • }*

  • }*
    //
    //void t1(iPhoneTouch t2)
    //
    //{
    *// *
    //if(t2.phase==iPhoneTouchPhase.)
    //{
    *// *
    *// *
    *// *
    *// *
    *// } *
    *// *
    // }
    }

I recently posted a working example on my blog of getting a UnityGUI list to scroll up and down in response to swipes. I walk through it a piece at a time, so I am hopeful that someone interested in handling swipes in general could learn from it.

The code is in C#, but it should be easy to port, the code is mostly if-then statements, numeric assignments, and comparisons.

1 Like

Thanks for the easily understandable code andeeee. :slight_smile:
I applied the code on a game object and thatā€™s supposed to make an iTween movement as a reaction to the swipe. I get the following error though:
Assets/scripts/SwipeScript.js (14,36): BCE0020: An instance of type ā€˜UnityEngine.Touchā€™ is required to access non static member ā€˜phaseā€™.
What does this mean? :-/

ok Iā€™d made a typo at the referred line and that caused the error - I apologiseā€¦

Just one thing: what values for comfortZone and minSwipeDist (in andeeeeā€™s script) would you recommend?

Also: shouldnā€™t the if condition in line 21, check to see if (touch.position.x - startPos.x) > comfortZone) for a vertical swipe?

I tried a large range of values (beginning from the obvious - I think - around 50 to100) but I get to achieve a swipe veeery difficult (I set the maxSwipeTime to a very large value to make sure my swipe speed is not the problem). Thatā€™s strange.

(Regarding andeeeeā€™s script)
I modified the script in a way that I avoid everything that has to do with the couldBeSwipe: boolean and strangely enough it works great.
Thanks so much andeeee, I was searching and searching and the script you suggested (with a few tiny modifications) did my job perfectly!!!

Hi schwertfisch ,

can u post that script for vertical swipe?

How can find the Direction of swipe Like Right to left Vice -Verse and Up to Bottom

prangya_p and kapilundan, Iā€™m really sorry for not having responded for so long, I hadnā€™t visited the thread and I wasnā€™t notified that there were replies to it (maybe I could change this from my settings), I guess my answer is not so useful after 50 days but Iā€™m posting it anyway as it could be useful to others at leastā€¦

I use the following script, that is attached to my character (something like a chess pawn) and will move it on a board horizontally or vertically, depending on the swipes. The swipes can be made anywhere on the screen and you donā€™t have to make them on the character.

var comfortZoneVerticalSwipe: float = 50; // the vertical swipe will have to be inside a 50 pixels horizontal boundary
var comfortZoneHorizontalSwipe: float = 50; // the horizontal swipe will have to be inside a 50 pixels vertical boundary
var minSwipeDistance: float = 14; // the swipe distance will have to be longer than this for it to be considered a swipe
//the following 4 variables are used in some cases that I donā€™t want my character to be allowed to move on the board (itā€™s a board game)
var allowGoUp: boolean = true;
var allowGoRight: boolean = true;
var allowGoLeft: boolean = true;
var allowGoDown: boolean = true;

function Update () {
if (Input.touchCount >0) {
var touch = Input.touches[0];

switch (touch.phase) { //following are 2 cases
case TouchPhase.Began: //here begins the 1st case
startPos = touch.position;
startTime = Time.time;

break; //here ends the 1st case

case TouchPhase.Ended: //here begins the 2nd case
var swipeTime = Time.time - startTime;
var swipeDist = (touch.position - startPos).magnitude;
var endPos = touch.position;

if ((Mathf.Abs(touch.position.x - startPos.x))<comfortZoneVerticalSwipe (swipeTime < maxSwipeTime) (swipeDist > minSwipeDistance) Mathf.Sign(touch.position.y - startPos.y)>0 !moving transform.position.z<3 allowGoUp)
{
//ā€¦ then go up
moving=true;
[code here, to make character move the way you want (upwards)]
}

if ((Mathf.Abs(touch.position.x - startPos.x))<comfortZoneVerticalSwipe (swipeTime < maxSwipeTime) (swipeDist > minSwipeDistance) Mathf.Sign(touch.position.y - startPos.y)<0 !moving transform.position.z>-3 allowGoDown)
{
//ā€¦ then go down
moving=true;
[code here, to make character move the way you want (downwards)]
}

if ((Mathf.Abs(touch.position.y - startPos.y))<comfortZoneHorizontalSwipe (swipeTime < maxSwipeTime) (swipeDist > minSwipeDistance) Mathf.Sign(touch.position.x - startPos.x)<0 !moving transform.position.x>-2 allowGoLeft)
{
//ā€¦ then go left
moving=true;
[code here, to make character move the way you want (to the left)]
}

if ((Mathf.Abs(touch.position.y - startPos.y))<comfortZoneHorizontalSwipe (swipeTime < maxSwipeTime) (swipeDist > minSwipeDistance) Mathf.Sign(touch.position.x - startPos.x)>0 !moving transform.position.x<2 allowGoRight)
{
//ā€¦then go right
moving=true;
[code here, to make character move the way you want (to the right)]
}
break; //here ends the 2nd case

}
}

Hey matt thank !!

Hey Everyone,

I thought Iā€™d post this in case anyone was looking for a C# version of a swipe script. I converted Andeeā€™s into it and made a few modifications:

  1. IPhoneTouch class is deprecated, so I converted it to use Input.Touches (I think someone did this earlier in javascript)

  2. When determining the swipe distance, for strict vertical swipes I wanted it to only take the Y values into consideration.

  3. The comfort zone comparison should be with touch.position.x not touch.position.y, so I fixed that.

  4. I created an enumeration for the swipe direction. The direction, along with the swipe time are exposed as public variables, lastSwipe and lastSwipeTime respectfully. You can toss this script on an empty game object and access those values from other scripts to determine vertical swipes.

  5. I also put in some debug messages to assist with fine tuning the comfort zone.

It should be pretty easy to modify for horizontal swipes too. Since I have to do that, I will probably post that soon as well.

using UnityEngine;
using System.Collections;

public class SwipeDetector : MonoBehaviour {

	// Values to set:
	public float comfortZone = 70.0f;
	public float minSwipeDist = 14.0f;
	public float maxSwipeTime = 0.5f;

	private float startTime;
	private Vector2 startPos;
	private bool couldBeSwipe;
	
	public enum SwipeDirection {
		None,
		Up,
		Down
	}
	
	public SwipeDirection lastSwipe = SwipeDetector.SwipeDirection.None;
	public float lastSwipeTime;
	
	void  Update() 
	{
		if (Input.touchCount > 0) 
		{
			Touch touch = Input.touches[0];
		
			switch (touch.phase) 
			{
				case TouchPhase.Began:
					lastSwipe = SwipeDetector.SwipeDirection.None;
                                        lastSwipeTime = 0;
					couldBeSwipe = true;
					startPos = touch.position;
					startTime = Time.time;
					break;
				
				case TouchPhase.Moved:
					if (Mathf.Abs(touch.position.x - startPos.x) > comfortZone) 
					{
						Debug.Log("Not a swipe. Swipe strayed " + (int)Mathf.Abs(touch.position.x - startPos.x) + 
					              "px which is " + (int)(Mathf.Abs(touch.position.x - startPos.x) - comfortZone) + 
					              "px outside the comfort zone.");
						couldBeSwipe = false;
					}
					break;
				case TouchPhase.Ended:
					if (couldBeSwipe)
					{
						float swipeTime = Time.time - startTime;
						float swipeDist = (new Vector3(0, touch.position.y, 0) - new Vector3(0, startPos.y, 0)).magnitude;
					
						if ((swipeTime < maxSwipeTime)  (swipeDist > minSwipeDist)) 
						{
							// It's a swiiiiiiiiiiiipe!
							float swipeValue = Mathf.Sign(touch.position.y - startPos.y);
						
							// If the swipe direction is positive, it was an upward swipe.
							// If the swipe direction is negative, it was a downward swipe.
							if (swipeValue > 0)
								lastSwipe = SwipeDetector.SwipeDirection.Up;
							else if (swipeValue < 0)
								lastSwipe = SwipeDetector.SwipeDirection.Down;
						
							// Set the time the last swipe occured, useful for other scripts to check:
							lastSwipeTime = Time.time;
							Debug.Log("Found a swipe!  Direction: " + lastSwipe);
						}
					}
					break;
			}
		}
	}
}
1 Like

Hummm, I also need a swipe in Unity.

How about an implementation of iOS native UIGestureRecognizer with the following subclasses: UITapGestureRecognizer [Pinch, Rotation, Swipe, Pan, LongPress]?

I havenā€™t looked yet, but I gather itā€™s not in Unity, right?