- Home /
Touch screen horizontal or vertical swipe
I need to move an object on a grid board, by a standard distance (eg 1 unit horizontally or vertically), depending on whether I swipe one finger horizontally or vertically. The distance is fixed as I mentioned and the direction will depend on whether I move from bottom to top, from left to right or vice versa.
As I understand I will have to use (or at least this could be a way to do it) the Touch.deltaPosition and the tan of the vector that my swipe will follow. This way, if I swipe from bottom to top, the vector that I follow has an angle fo 90degrees (in relation to the xy coordinate system of the board my object moves on) and its tan is infinite. Using if I will then tell my object to move one unit up if this kind of swipe is input.
The problem is I dont know how to script that, no matter how much I browse through the Script Reference and the Forum. Any hint would be very appreciated.
Alex :-)
Answer by azzogat · Nov 28, 2010 at 06:53 PM
You should check andee's post over at the forums. It worked great for me (for a similar situation):
http://forum.unity3d.com/threads/48601-Swipe-help-please?highlight=swipe
(4th post down)
Just check for touch.position.x as well.
a 1000 thanks for the immediate response. I feel bad for not having found the suggested thread but I really searched a lot. It helped very much :-)
No need, I remember searching for it for what seemed like forever back then. It's literally buried under a ton of c##p.
nice one! could you please post some working code here? especially good values of comfortZone, $$anonymous$$SwipeDist and maxSwipeTime... ;-)
We've sidelined the project that used that piece of code. I remember it was pretty easy to get a workable user experience. Just experiment with the values and you'll get there in no time.
Answer by Toonk · Jan 03, 2015 at 04:19 PM
TO ANYONE WHO HAS/HAD THE SAME QUESTION:
I actually took andee's code, transphered it to C#, and improved it a litte:
The major difference in contrast to andee's script is, that for the swipe to be registered you dont have to wait till your finger leaves the touchscreen, and that you don't have to swipe "totally horizonta"l (Just the x-difference gets measured --> swiping is (way) more convinient). As of now, this is as i find the way it is implemented in most games/apps nowdays.
//If you'd like to do the same for a vertical swipe, just exchange every ".x" with a ".y" .
Feel free to use :-) -Toonk
public float minSwipeDist, maxSwipeTime; bool couldBeSwipe;
IEnumerator checkHorizontalSwipes () //Coroutine, wich gets Started in "Start()" and runs over the whole game to check for swipes
{
while (true) { //Loop. Otherwise we wouldnt check continoulsy ;-)
foreach (Touch touch in Input.touches) { //For every touch in the Input.touches - array...
switch (touch.phase) {
case TouchPhase.Began: //The finger first touched the screen --> It could be(come) a swipe
couldBeSwipe = true;
startPos = touch.position; //Position where the touch started
swipeStartTime = Time.time; //The time it started
break;
case TouchPhase.Stationary: //Is the touch stationary? --> No swipe then!
couldBeSwipe = false;
break;
}
float swipeTime = Time.time - swipeStartTime; //Time the touch stayed at the screen till now.
float swipeDist = Mathf.Abs (touch.position.x - startPos.x); //Swipedistance
if (couldBeSwipe && swipeTime < maxSwipeTime && swipeDist > minSwipeDist) {
// It's a swiiiiiiiiiiiipe!
couldBeSwipe = false; //<-- Otherwise this part would be called over and over again.
if (Mathf.Sign (touch.position.x - startPos.x) == 1f) { //Swipe-direction, either 1 or -1.
//Right-swipe
} else {
//Left-swipe
}
}
}
yield return null;
}
Answer by ShawnFeatherly · May 12, 2015 at 10:52 PM
I had an issue with TouchPhase randomly being stationary in what I considered a fast valid swipe. I got around this issue by modifying andee's code to require stationary to continuously be the phase for 6 frames before it'll cancel.
Here's the full code:
public class TouchGesture
{
[System.Serializable]
public class GestureSettings
{
public float minSwipeDist = 100;
public float maxSwipeTime = 10;
}
private GestureSettings settings;
private float swipeStartTime;
private bool couldBeSwipe;
private Vector2 startPos;
private int stationaryForFrames;
private TouchPhase lastPhase;
public TouchGesture(GestureSettings gestureSettings)
{
this.settings = gestureSettings;
}
public IEnumerator CheckHorizontalSwipes(Action onLeftSwipe, Action onRightSwipe) //Coroutine, which gets Started in "Start()" and runs over the whole game to check for swipes
{
while (true)
{ //Loop. Otherwise we wouldnt check continuously ;-)
foreach (Touch touch in Input.touches)
{ //For every touch in the Input.touches - array...
switch (touch.phase)
{
case TouchPhase.Began: //The finger first touched the screen --> It could be(come) a swipe
couldBeSwipe = true;
startPos = touch.position; //Position where the touch started
swipeStartTime = Time.time; //The time it started
stationaryForFrames = 0;
break;
case TouchPhase.Stationary: //Is the touch stationary? --> No swipe then!
if (isContinouslyStationary(frames:6))
couldBeSwipe = false;
break;
case TouchPhase.Ended:
if (isASwipe(touch))
{
couldBeSwipe = false; //<-- Otherwise this part would be called over and over again.
if (Mathf.Sign(touch.position.x - startPos.x) == 1f) //Swipe-direction, either 1 or -1.
onRightSwipe(); //Right-swipe
else
onLeftSwipe(); //Left-swipe
}
break;
}
lastPhase = touch.phase;
}
yield return null;
}
}
private bool isContinouslyStationary(int frames)
{
if (lastPhase == TouchPhase.Stationary)
stationaryForFrames++;
else // reset back to 1
stationaryForFrames = 1;
return stationaryForFrames > frames;
}
private bool isASwipe(Touch touch)
{
float swipeTime = Time.time - swipeStartTime; //Time the touch stayed at the screen till now.
float swipeDist = Mathf.Abs(touch.position.x - startPos.x); //Swipe distance
return couldBeSwipe && swipeTime < settings.maxSwipeTime && swipeDist > settings.minSwipeDist;
}
}
A script watching for swipes would look like:
public TouchGesture.GestureSettings GestureSetting;
private TouchGesture touch;
void Start()
{
touch = new TouchGesture(this.GestureSetting);
StartCoroutine(touch.CheckHorizontalSwipes(
onLeftSwipe: () => { HideMenuHome(); },
onRightSwipe: () => { ShowMenuHome(); }
));
}
Different sensitivity of TouchPhase.Stationary
between devices is likely due to the DPI of the device. A better fix, than what I did here, might be to factor in the DPI to determine how many continuously stationary frames make it no longer a swipe.
I'm really a newbie, how can i make the command "Action" work in unity?
Either add a "using System;" at the top of the file that has the Action keyword. Or replace every instance of the Action keyword with System.Action, as @Simit pointed out.
I have created a game object then applied the TouchGesture script to that object But nothing is happening when I run the project. Did I am missing something -- Can anyone tell me the Step by step process. Thanks
Answer by col000r · Aug 17, 2011 at 12:46 PM
SwipeControl does horizontal+vertical swiping: Website/video: http://gameassets.net/swipeControl.html Webplayer-Demo: http://gameassets.net/demo/swipeControl.html
Your answer
Follow this Question
Related Questions
Swipe control for circle (Can do swipe left/right) 2 Answers
Joystick Zone + Screen-swipe touch input clash. Solution??? 1 Answer
Detect swipe along 3d arrows 1 Answer
swipe distance detection dont work 2 Answers
Help with Uniflow Gallery swipe 0 Answers