• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by schwertfisch · Nov 28, 2010 at 06:14 PM · touchswipehorizontalvertical

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 :-)

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

6 Replies

· Add your reply
  • Sort: 
avatar image
6
Best Answer

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.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image schwertfisch · Nov 29, 2010 at 06:52 PM 0
Share

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 :-)

avatar image azzogat · Nov 29, 2010 at 08:40 PM 0
Share

No need, I remember searching for it for what seemed like forever back then. It's literally buried under a ton of c##p.

avatar image headkitgames · Jan 20, 2011 at 03:29 PM 0
Share

nice one! could you please post some working code here? especially good values of comfortZone, minSwipeDist and maxSwipeTime... ;-)

avatar image azzogat · Jan 21, 2011 at 08:57 PM 0
Share

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.

avatar image
5

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;
                 }
 
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Decochon_H · Aug 19, 2018 at 06:10 PM 0
Share

This is a really great solution. Thanks a lot!

avatar image
3

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.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Leon700 · Jul 11, 2015 at 06:23 AM 0
Share

I'm really a newbie, how can i make the command "Action" work in unity?

avatar image ShawnFeatherly · Jul 16, 2015 at 10:39 PM 0
Share

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.

avatar image mujaffars · Mar 11, 2016 at 06:09 PM 0
Share

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

avatar image
0

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

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by _Simit_ · Jul 14, 2015 at 04:32 PM

@Leon700: Just pass System.Action along with the Swipe Direction Variable (onLeftSwipe or onRightSwipe in this case) as the argument.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

7 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Diagonal swipe issues on Android 1 Answer

Moving player using cam.ScreenToWorldPoint, with camera smooth following the player 1 Answer

Get walk animation to play on horizontal and vertical axis presses. 2 Answers

How can I play different animations depending on the direction my character is moving? 1 Answer

iPhone - How to calculate a decent touch swipe speed? 2 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges