- Home /
How to move player once per swipe
Hi the SwipeDetection script im using for detecting swipes works perfect. In this script I have an enum Swipe with all the states. I set the swipeDirection variable of type Swipe to the state respective to the swipe direction performed. Now In my second script MoveWithSwipe I have a method movePlayer which checks the state of the swipe and moves the player one unit that direction. However there is a problem where sometimes the player moves multiple times per swipe rather than moving only once. Can you help me find why this is happening?
           using UnityEngine;
           using System.Collections;
           
           public enum Swipe
           {
               None,
               Up,
               Down,
               Left,
               Right}
           ;
           
           public class SwipeDetection : MonoBehaviour
           {
               public float minSwipeLength = 50f;
               Vector2 firstPressPos;
               Vector2 secondPressPos;
               Vector2 currentSwipe;
               public Transform playerPrefab;
               public float timeLeft = 100;
           
               // static so that refence to this script is not needed by other scripts
               public static Swipe swipeDirection;
           
               void Update ()
               {
                   DetectSwipe ();
                   Debug.Log (swipeDirection);
               }
           
               public void DetectSwipe ()
               {
                   
                   if (Input.touches.Length > 0) {
                       Touch t = Input.GetTouch (0);
           
                       if (t.phase == TouchPhase.Began) {
                           firstPressPos = new Vector2 (t.position.x, t.position.y);
                       }
           
                       if (t.phase == TouchPhase.Ended) {
                           secondPressPos = new Vector2 (t.position.x, t.position.y);
                           currentSwipe = new Vector3 (secondPressPos.x - firstPressPos.x, secondPressPos.y - firstPressPos.y);
           
                           // Make sure it was a legit swipe, not a tap
                           if (currentSwipe.magnitude < minSwipeLength) {
                               swipeDirection = Swipe.None;
                               return;
                           }
           
                           currentSwipe.Normalize ();
           
                           // Swipe up
                           if (currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) {
                               swipeDirection = Swipe.Up;
                               Debug.Log ("Swiped UP");
                               //playerPrefab.Translate(0,1,0);
                           } 
                           // Swipe down
                           else if (currentSwipe.y < 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f) {
                               swipeDirection = Swipe.Down;
                               Debug.Log ("Swiped DOWN");
                               //playerPrefab.Translate(0,-1,0);
           
                           }
                           // Swipe left
                           else if (currentSwipe.x < 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) {
                               swipeDirection = Swipe.Left;
                               Debug.Log ("Swiped LEFT");
                               //playerPrefab.Translate(-1,0,0);
           
                           }
                           // Swipe right
                           else if (currentSwipe.x > 0 && currentSwipe.y > -0.5f && currentSwipe.y < 0.5f) {
                               swipeDirection = Swipe.Right;
                               Debug.Log ("Swiped RIGHT");
                                   
                               //playerPrefab.Translate(1,0,0);
                           }
                       }
                   } else {
                       swipeDirection = Swipe.None;   
                   }
           
               }
           }
This is the second script
           using UnityEngine;
           using System.Collections;
           
           public class MoveWithSwipe : MonoBehaviour {
           
               // Use this for initialization
           
               //what to move
               public Transform playerPrefab;
               void Start () {
                   
               }
               
               // Update is called once per frame
               void Update () {
                   movePlayer(SwipeDetection.swipeDirection);
               }
           
               public void movePlayer (Swipe swipeDirection)
               {
                       switch (swipeDirection) {
                       case Swipe.Up:
                           playerPrefab.Translate (0, 1, 0);
                           Debug.Log ("Move UP");
                           break;
                       case Swipe.Down:
                           playerPrefab.Translate (0, -1, 0);
                           Debug.Log ("Move DOWN");
                           break;
                       case Swipe.Right:
                           playerPrefab.Translate (1, 0, 0);
                           Debug.Log ("Move RIGHT");
                           break;
                       case Swipe.Left:
                           playerPrefab.Translate (-1, 0, 0);
                           Debug.Log ("Move LEFT");
                           break;
                       case Swipe.None:
                           break;
                       }
                   }
           
               }
Answer by MadDevil · Feb 01, 2016 at 06:12 AM
Upadate is called multiple times in single second, due to which the MovePlayer function is called multiple times in your script.
My suggestion is to add a boolean, so that it will be called once and the player can move only once.
something like this will probably work. bool temp;
 void Update()
 {
 if(temp)
 {
 temp = false;
 MovePlayer(direction);
 }
 }
You can make the boolean true after you have registered your swipe direction.
Answer by Imankit · Feb 01, 2016 at 09:28 AM
This is happening because you are calculating swipes and moving player in update. You have to make a timer after which a swipe detection activates. Something like this
  bool CanSwipe = true;
     
     void ActivateSwipeDetection(){
           CanSwipe = true;
     }
     void Update(){
     
         if(canswipe){
             // calculate swipe
            if(swiped){
                  canswipe = false;
                  Invoke("ActivateSwipeDetection",0.5f);
                  // Here you have to move player
         }
       }
     }
I get what you have suggested. But respectively i feel there may be a better way to do it. Let me explain why i feel that way. The first script swipeDetection changes state of swipeDirection to the right left etc based on my swipe performed. Now in the second script I wanted to move the player based on the state. In order to check which state i am in i had to put the method movePlayer() in update() since state can change any frame. The problem here is that sometimes when i swipe, it only moves once but sometimes it moves like 10 times per swipe. Thats why i feel there is something else thats wrong. I may be wrong. But for now i will implement this. Thanks @ankit.tiks007 and @$$anonymous$$adDevil
Also using bool removes the need of states as i wanted. So this doesn't help solve my problem as i had other ways i can implement other than using states.
You can thumbs up if you appreciate my answer.. Just for the karma.. ;)
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                