C# 在不抬起手指的情况下检测刷卡

C# 在不抬起手指的情况下检测刷卡,c#,unity3d,touch,swipe,C#,Unity3d,Touch,Swipe,我正在实施特定类型的触摸控制器。 玩家需要将手指放在屏幕上才能移动。 无需抬起手指,玩家可以在移动的同时向不同方向滑动以改变方向。 一旦手指抬起,玩家就停止移动 很难隔离特定的滑动(即屏幕上画的线),忽略任何不打算画线的其他移动。 例如,当玩家的手指处于“静止”状态时,手指会轻微移动,这会打乱我的算法 我考虑过不同的方法,比如存储最后几次触摸并对其进行评估,以确定是否有刷击,但无法正确实施 这是我到目前为止试过的。大多数情况下,它工作得很好,但通常情况下,玩家的动作不稳定,与我的意图完全相反 u

我正在实施特定类型的触摸控制器。 玩家需要将手指放在屏幕上才能移动。 无需抬起手指,玩家可以在移动的同时向不同方向滑动以改变方向。 一旦手指抬起,玩家就停止移动

很难隔离特定的滑动(即屏幕上画的线),忽略任何不打算画线的其他移动。 例如,当玩家的手指处于“静止”状态时,手指会轻微移动,这会打乱我的算法

我考虑过不同的方法,比如存储最后几次触摸并对其进行评估,以确定是否有刷击,但无法正确实施

这是我到目前为止试过的。大多数情况下,它工作得很好,但通常情况下,玩家的动作不稳定,与我的意图完全相反

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TouchInputHandler : AbstractInputHandler {

    private const int SWIPE_MIN_DISTANCE = 35;

    private Vector2 touchStartPoint;

    private Vector2 touchMovePoint;

    void Update () {
        Touch[] touches = Input.touches;
        if (touches.Length == 1) {
            Touch firstTouch = touches [0];
            if (firstTouch.phase == TouchPhase.Began) {
                this.touchStartPoint = firstTouch.position;
                fireNextDirectionChanged (currentDirection);
            } else if (firstTouch.phase == TouchPhase.Moved) {
                this.touchMovePoint = firstTouch.position;
                if (Vector2.Distance(touchStartPoint, touchMovePoint) > SWIPE_MIN_DISTANCE) {
                    detectSwipeDirection ();
                }
            } else if (firstTouch.phase == TouchPhase.Stationary) {
                touchStartPoint.x = touchMovePoint.x;
                touchStartPoint.y = touchMovePoint.y;
            } else if (firstTouch.phase == TouchPhase.Ended) {
                fireNextDirectionChanged (Constants.Direction.NONE);
            }
        }
    }

    private void detectSwipeDirection() {
        float xDiff = touchMovePoint.x - touchStartPoint.x;
        float yDiff = touchMovePoint.y - touchStartPoint.y;
        Constants.Direction nextDirection;
        bool yGreater = Mathf.Abs(yDiff) >= Mathf.Abs(xDiff);
        if (yGreater) {
            // direction is up or down
            nextDirection = yDiff < 0 ? Constants.Direction.DOWN : Constants.Direction.UP;
        } else {
            // direction is left or right
            nextDirection = xDiff < 0 ? Constants.Direction.LEFT : Constants.Direction.RIGHT;
        }

        if (nextDirection != this.currentDirection)
        {
            fireNextDirectionChanged (nextDirection);
            this.currentDirection = nextDirection;
        }
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类TouchInputHandler:AbstractInputHandler{
私用常数内扫距离=35;
私有矢量2触摸起点;
私有向量2接触点;
无效更新(){
触摸[]触摸=输入。触摸;
if(touchs.Length==1){
Touch firstTouch=触摸[0];
if(firstTouch.phase==TouchPhase.start){
this.touchStartPoint=firstTouch.position;
FirenextDirection已更改(当前方向);
}else if(firstTouch.phase==TouchPhase.Moved){
this.touchMovePoint=firstTouch.position;
if(矢量2.距离(触摸起点、触摸移动点)>滑动距离){
检测方向();
}
}else if(firstTouch.phase==TouchPhase.stative){
touchStartPoint.x=touchMovePoint.x;
touchStartPoint.y=touchMovePoint.y;
}else if(firstTouch.phase==TouchPhase.end){
FireNextDirection已更改(常量.方向.无);
}
}
}
私有void detectSwipeDirection(){
float xDiff=touchMovePoint.x-touchStartPoint.x;
float yDiff=touchMovePoint.y-touchStartPoint.y;
常数。方向下一个方向;
bool-yGreater=Mathf.Abs(yDiff)>=Mathf.Abs(xDiff);
if(yGreater){
//方向是向上还是向下
nextDirection=yDiff<0?Constants.Direction.DOWN:Constants.Direction.UP;
}否则{
//方向是左还是右
nextDirection=xDiff<0?Constants.Direction.LEFT:Constants.Direction.RIGHT;
}
if(nextDirection!=此.currentDirection)
{
FireNextDirection已更改(nextDirection);
this.currentDirection=nextDirection;
}
}
}

我想您只是忘记了在
触摸阶段将上一个触摸位置设置为当前位置的一行。已移动
块。只需添加
touchStartPoint=this.touchMovePoint应该可以工作(仅使用鼠标输入进行测试,但逻辑保持不变)

我还评论了
TouchPhase.stational
块:我感觉它就像我之前建议的那样,但只有当手指完全不动的时候。最后的代码如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TouchInputHandler : AbstractInputHandler
{

    private const int SWIPE_MIN_DISTANCE = 35;

    private Vector2 touchStartPoint;

    private Vector2 touchMovePoint;

    void Update()
    {
        Touch[] touches = Input.touches;
        if(touches.Length == 1)
        {
            Touch firstTouch = touches[0];
            if(firstTouch.phase == TouchPhase.Began)
            {
                this.touchStartPoint = firstTouch.position;
                this.currentDirection = Constants.Direction.NONE;
                fireNextDirectionChanged(currentDirection);
            }
            else if(firstTouch.phase == TouchPhase.Moved)
            {
                this.touchMovePoint = firstTouch.position;
                if(Vector2.Distance(touchStartPoint, touchMovePoint) > SWIPE_MIN_DISTANCE)
                {
                    detectSwipeDirection();
                }
                touchStartPoint = this.touchMovePoint; // <= NEW !
            }
            //else if(firstTouch.phase == TouchPhase.Stationary)
            //{
            //    touchStartPoint.x = touchMovePoint.x;
            //    touchStartPoint.y = touchMovePoint.y;
            //}
            else if(firstTouch.phase == TouchPhase.Ended)
            {
                this.currentDirection = Constants.Direction.NONE;
                fireNextDirectionChanged(Constants.Direction.NONE);
            }
        }
    }

    private void detectSwipeDirection()
    {
        float xDiff = touchMovePoint.x - touchStartPoint.x;
        float yDiff = touchMovePoint.y - touchStartPoint.y;
        Constants.Direction nextDirection;
        bool yGreater = Mathf.Abs(yDiff) >= Mathf.Abs(xDiff);
        if(yGreater)
        {
            // direction is up or down
            nextDirection = yDiff < 0 ? Constants.Direction.DOWN : Constants.Direction.UP;
        }
        else
        {
            // direction is left or right
            nextDirection = xDiff < 0 ? Constants.Direction.LEFT : Constants.Direction.RIGHT;
        }

        if(nextDirection != this.currentDirection)
        {
            fireNextDirectionChanged(nextDirection);
            this.currentDirection = nextDirection;
        }
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类TouchInputHandler:AbstractInputHandler
{
私用常数内扫距离=35;
私有矢量2触摸起点;
私有向量2接触点;
无效更新()
{
触摸[]触摸=输入。触摸;
if(touchs.Length==1)
{
Touch firstTouch=触摸[0];
if(firstTouch.phase==TouchPhase.start)
{
this.touchStartPoint=firstTouch.position;
this.currentDirection=Constants.Direction.NONE;
FirenextDirection已更改(当前方向);
}
else if(firstTouch.phase==TouchPhase.Moved)
{
this.touchMovePoint=firstTouch.position;
if(矢量2.距离(触摸起点、触摸移动点)>滑动距离)
{
检测方向();
}
touchStartPoint=this.touchMovePoint;//=Mathf.Abs(xDiff);
if(yGreater)
{
//方向是向上还是向下
nextDirection=yDiff<0?Constants.Direction.DOWN:Constants.Direction.UP;
}
其他的
{
//方向是左还是右
nextDirection=xDiff<0?Constants.Direction.LEFT:Constants.Direction.RIGHT;
}
if(nextDirection!=此.currentDirection)
{
FireNextDirection已更改(nextDirection);
this.currentDirection=nextDirection;
}
}
}
另外,当使用基于游戏内距离的距离来检测刷卡时,如果您想将项目移植到多分辨率设备(在
Start()上),我建议在某处添加一个
Screen.width/height
比率
使用
private const int BASE\u Screen\u width=1024;
执行类似的操作


希望这能有所帮助,

@Programmer,这个问题怎么会重复?你读过问题了吗?两个问题都说“检测刷卡”。至于“不举起手指”,检查答案。它的
detectSwipeOnlyAfterRelease
变量设置为false。请告诉我,什么不能使这成为一个副本?@程序员是的,你是对的,我在那里阅读了答案,根据我的需要对其进行了一些修改,并解决了我的问题。我是发布解决方案并接受它,还是将其作为副本关闭?它已经关闭,但你可以把你自己的答案。也可以链接到你修改过的原始代码。嘿,伙计,试试看