且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

统一在Android上滑动手势

更新时间:2023-02-27 11:09:57

您面临的问题是因为您已经在TouchPhase.Ended中进行了检查.您要做的是在TouchPhase.Moved中执行检查,其值变化较小(您在Ended中使用80,如果代码不起作用,请尝试10之类的东西)

The issue you're facing is because you've done your checks in the TouchPhase.Ended. What you want to do is perform your checks in TouchPhase.Moved, with a smaller change in value (you're using 80 in Ended, try something like 10 if you the code doesn't work)

Unity在TouchPhase上的文档 http://docs.unity3d.com/ScriptReference/TouchPhase.html >

Unity's documentation on TouchPhase http://docs.unity3d.com/ScriptReference/TouchPhase.html

    foreach(Touch touch in Input.touches)
    {

        if (touch.phase == TouchPhase.Began)
        {
            fingerStart = touch.position;
            fingerEnd  = touch.position;
        }
        if (touch.phase == TouchPhase.Moved )
        {
            fingerEnd = touch.position;

            if((fingerStart.x - fingerEnd.x) > 80 || 
               (fingerStart.x - fingerEnd.x) < -80) // Side to side Swipe
            {
                leftRight ++;
            }
            else if((fingerStart.y - fingerEnd.y) < -80 || 
                    (fingerStart.y - fingerEnd.y) > 80) // top to bottom swipe
            {
                upDown ++;

            }
            if(leftRight >= 3){

                leftRight = 0;
            }
            if(upDown >= 4){

                upDown = 0;
            }

            //After the checks are performed, set the fingerStart & fingerEnd to be the same
            fingerStart = touch.position;   

        }
        if(touch.phase == TouchPhase.Ended)
        {
            leftRight = 0;
            upDown = 0;
            fingerStart = Vector2.zero;
            fingerEnd = Vector2.zero;
        }




如果要显式检查图案(即,左->右->左),而不是像检查代码那样仅检查它是否有横向/纵向运动,请尝试以下代码.只记得包括System.Collentions.Generic&System.Linq命名空间




If you want to explicitly check for a pattern (i.e. left -> right -> left), rather than just checking if it's some lateral / vertical movement as the code you have will do, try the below code. Just remember to include System.Collentions.Generic & System.Linq namespaces

private Vector2 fingerStart;
private Vector2 fingerEnd;

public enum Movement
{
    Left,
    Right, 
    Up,
    Down
};

public List<Movement> movements = new List<Movement>();


void Update () {
    foreach(Touch touch in Input.touches)
    {

        if (touch.phase == TouchPhase.Began) {
            fingerStart = touch.position;
            fingerEnd  = touch.position;
        }

        if(touch.phase == TouchPhase.Moved) {
            fingerEnd = touch.position;

            //There is more movement on the X axis than the Y axis
            if(Mathf.Abs(fingerStart.x - fingerEnd.x) > Mathf.Abs(fingerStart.y - fingerEnd.y)) {

                //Right Swipe
                if((fingerEnd.x - fingerStart.x) > 0)
                    movements.Add(Movement.Right);
                //Left Swipe
                else
                    movements.Add(Movement.Left);

            }

            //More movement along the Y axis than the X axis
            else {
                //Upward Swipe
                if((fingerEnd.y - fingerStart.y) > 0)
                    movements.Add(Movement.Up);
                //Downward Swipe
                else
                    movements.Add(Movement.Down);
            }
            //After the checks are performed, set the fingerStart & fingerEnd to be the same
            fingerStart = touch.position;   

            //Now let's check if the Movement pattern is what we want
            //In this example, I'm checking whether the pattern is Left, then Right, then Left again
            Debug.Log (CheckForPatternMove(0, 3, new List<Movement>() { Movement.Left, Movement.Right, Movement.Left } ));
        }


        if(touch.phase == TouchPhase.Ended)
        {
            fingerStart = Vector2.zero;
            fingerEnd = Vector2.zero;
            movements.Clear();
        }
    }
}


private bool CheckForPatternMove (int startIndex, int lengthOfPattern, List<Movement> movementToCheck) {

    //If the currently stored movements are fewer than the length of the pattern to be detected
    //it can never match the pattern. So, let's get out
    if(lengthOfPattern > movements.Count)
        return false;

    //In case the start index for the check plus the length of the pattern
    //exceeds the movement list's count, it'll throw an exception, so lets get out
    if(startIndex + lengthOfPattern > movements.Count)
        return false;

    //Populate a temporary list with the respective elements
    //from the movement list
    List<Movement> tMovements = new List<Movement>();
    for(int i = startIndex; i < startIndex + lengthOfPattern; i++)
        tMovements.Add(movements[i]);

    //Now check whether the sequence of movements is the same as the pattern you want to check for
    //The SequenceEqual method is in the System.Linq namespace
    return tMovements.SequenceEqual(movementToCheck);
}



编辑作为示例添加了更多代码



EDIT Added some more code as a sample

    //The idea of a pattern match is to check for the exact same set of swipe gesture.
    //This requires the following conditions to be met
    // (a) The List of movements that need to be checked must be at least as long as the List of movements to check against.
    // (b) The correct indices should be used for the startIndex. In this case I'm just using 0 as the startIndex.
    // (c) Remember to clear the List right after you get a true return from the method, otherwise the next return will most likely be a false. 

    //Example - Training set is Left -> Right -> Left (This is what we want to check)
    // Step 1 - User swipes LEFT, method returns false because there are too few Movements to check
    // Step 2 - User swipes RIGHT, method returns false (same reason as above)

    // Step 3a - User swipes RIGHT (L, R, R now) - false, incorrect pattern (L, R, R instead of L, R, L)
    // Step 3b - User swipes LEFT (L, R, L now) - TRUE, Correct pattern!

    //Immediately clear if Step 3b happens otherwise Step 4 will occur

    // Step 4 - User swipes L or R (direction is immaterial right now), and method will return FALSE
    // if you use the last three indexes!



    //Pre-populating the movements List with L, R, L
    movements = new List<Movement>()
    {
        Movement.Left,
        Movement.Right,
        Movement.Left
    };

    //Checking a match against an L, R, L training set
    //This prints true to the console
    Debug.Log (CheckForPatternMove(0, 3, new List<Movement>() { Movement.Left, Movement.Right, Movement.Left }  ));





这是我的Update函数的外观.注意Input.touch上GetMouseButton的用法

Here's how my Update function looks like. Note the usage of GetMouseButton over Input.touch

void Update () {

    //Example usage in Update. Note how I use Input.GetMouseButton instead of Input.touch

    //GetMouseButtonDown(0) instead of TouchPhase.Began
    if (Input.GetMouseButtonDown(0)) {
        fingerStart = Input.mousePosition;
        fingerEnd  = Input.mousePosition;
    }

    //GetMouseButton instead of TouchPhase.Moved
    //This returns true if the LMB is held down in standalone OR
    //there is a single finger touch on a mobile device
    if(Input.GetMouseButton(0)) {
        fingerEnd = Input.mousePosition;

        //There was some movement! The tolerance variable is to detect some useful movement
        //i.e. an actual swipe rather than some jitter. This is the same as the value of 80
        //you used in your original code.
        if(Mathf.Abs(fingerEnd.x - fingerStart.x) > tolerance || 
           Mathf.Abs(fingerEnd.y - fingerStart.y) > tolerance) {

            //There is more movement on the X axis than the Y axis
            if(Mathf.Abs(fingerStart.x - fingerEnd.x) > Mathf.Abs(fingerStart.y - fingerEnd.y)) {
                //Right Swipe
                if((fingerEnd.x - fingerStart.x) > 0)
                    movements.Add(Movement.Right);
                //Left Swipe
                else
                    movements.Add(Movement.Left);
            }

            //More movement along the Y axis than the X axis
            else {
                //Upward Swipe
                if((fingerEnd.y - fingerStart.y) > 0)
                    movements.Add(Movement.Up);
                //Downward Swipe
                else
                    movements.Add(Movement.Down);
            }

            //After the checks are performed, set the fingerStart & fingerEnd to be the same
            fingerStart = fingerEnd;

            //Now let's check if the Movement pattern is what we want
            //In this example, I'm checking whether the pattern is Left, then Right, then Left again
            Debug.Log (CheckForPatternMove(0, 3, new List<Movement>() { Movement.Left, Movement.Right, Movement.Left } ));
        }
    }

    //GetMouseButtonUp(0) instead of TouchPhase.Ended
    if(Input.GetMouseButtonUp(0)) {
        fingerStart = Vector2.zero;
        fingerEnd = Vector2.zero;
        movements.Clear();
    }


}