Unity3d android开发之触摸操作识别-双击,滑动去噪处理

  在android上开发unity游戏,和在IOS上差不多,但是还是有许多细微的差别的,这可能是由于系统或者硬件问题导致的差异吧,比较典型的就是-触摸屏上实现双击的差别。

  Unity3d 官方API文档上告诉我们一件事,http://docs.unity3d.com/Manual/MobileInput.html ,如图

  

  你看他说,IOS设备就可以通过tapcontrol来判断是否有双击产生,然而android设备并没有这个功能。原因不管,看到这里我们就知道了,要想判断双击事件,还得靠自己手动写代码实现了。其实,模仿windows的鼠标双击机制,我们完全可以利用已有的API对双击进行识别,比如单击后,先不进行单击操作,而是进行双击监测,监测0.1秒内是否又有新的触摸手指触摸到了屏幕,如果有,则认为整个时间连起来算一个双击,而忽略前面的单击,如果0.1秒过去,没有任何新的响应,我们就继续处理0.1秒前的单击时间,记得在进行双击监测前,保存下当初那一帧的数据,否则,0.1秒后,你再处理单击事件的时候,就物是人非了。

  废话不多说,直接上核心代码图

  

if ( touchCount == 0 )        //手指没按屏幕或者松开
    {
        ResetControlState();
        
        if(typeOfOperation == E_OperationType.waitforDoubleTouch)        //在等待双击状态的0.1秒内,并没有手指按下,则认为刚才那个是单击
        {
            timeIntervalOfTouch = Time.time - fisrtTouchLeaveTime;    
            if(timeIntervalOfTouch >0.1)
            {
                typeOfOperation = E_OperationType.noCommand;                                        
                stateofmoving = E_MovingState.Continuous;    //启动持续行走模式
                switchflag =1;
                moving = true;
            }
        }    
        totalcount =0;    
    }
    else 
    {
        
        if(Input.GetTouch(0).phase == TouchPhase.Stationary )    //按住不放的状态下才算
            totalcount  += touchCount;        //如果持续按住不放,则累加,按照经验值,1秒钟可以累加50次
        
        
        var i : int;
        var touch : Touch;
        var theseTouches = Input.touches;
        
        var touch0 : Touch;
        var touch1 : Touch;
        var gotTouch0 = false;
        var gotTouch1 = false;        
        
        // Check if we got the first finger down
        if ( state == E_ControlState.WaitingForFirstTouch )        //手指按下的瞬间····
        {
            for ( i = 0; i < touchCount; i++ )
            {
                touch = theseTouches[ i ];
        
                if ( touch.phase != TouchPhase.Ended
                    && touch.phase != TouchPhase.Canceled )
                {
                    state = E_ControlState.HandleFirstTouch;
                    firstTouchTime = Time.time;
                    fingerDown[ 0 ] = touch.fingerId;
                    fingerDownPosition[ 0 ] = touch.position;
                    fingerDownFrame[ 0 ] = Time.frameCount;
                    break;
                }
            }
        }
        
        // Wait to see if a second finger touches down. Otherwise, we will
        // register this as a character move                    
        if ( state == E_ControlState.HandleFirstTouch )    //手指按下之后,一直处于这个状态
        {
            for ( i = 0; i < touchCount; i++ )
            {
                touch = theseTouches[ i ];

                if ( touch.phase != TouchPhase.Canceled )
                {
                    if ( touchCount == 1 )        //依然是一个手指
                    {
                    //    var deltaSinceDown = touch.position - fingerDownPosition[ 0 ];
                        
                        // Either the finger is held down long enough to count
                        // as a move or it is lifted, which is also a move. 
                        if ( touch.fingerId == fingerDown[ 0 ]  )
                        {
                            if(touch.phase == TouchPhase.Ended)    //手指离开的瞬间启动
                            {
                                if(maxmovecount >5)
                                {
                                    typeOfOperation = E_OperationType.slidingtouch;        //滑动触摸单击
                                    state = E_ControlState.WaitingForFirstTouch;
                                    maxmovecount =0;
                                }
                                else
                                {
                                    timeOfFingerStay =Time.time - firstTouchTime;        //计算手指停留的时间
                                    if(timeOfFingerStay > doubleTouchTimeLimit)        //手指停留时间大于双击时限算一次单击
                                    {
                                        if(typeOfOperation !=E_OperationType.singleTouched)
                                            typeOfOperation = E_OperationType.singleTouched;                                        
                                        state = E_ControlState.MovingCharacter;
                                    }
                                    else{        //手指停留时间小于双击时限,则认为有可能发生双击,此时要检测若干时间内是否再有手指按下,无手指按下,则按单击处理
                                        
                                        if(typeOfOperation !=E_OperationType.waitforDoubleTouch && typeOfOperation !=E_OperationType.doubleTouched)
                                        {
                                            typeOfOperation = E_OperationType.waitforDoubleTouch;
                                            fisrtTouchLeaveTime = Time.time;        //记下手指离开的时间,以便计算下次再按的时候的时间间隔
                                            state = E_ControlState.WaitingForFirstTouch;
                                        }
                                    }
                                }
                                
                                //根据状态做出响应
                                OnSingleTouchEnd();
                                    
                                
                            } 
                            
                            if(touch.phase ==TouchPhase.Began && typeOfOperation ==E_OperationType.waitforDoubleTouch)
                            {
                                timeIntervalOfTouch = Time.time - fisrtTouchLeaveTime;    //计算两次touch的间隔时间,间隔时间小于0.2秒,则认为是双击
                                if(timeIntervalOfTouch < 0.2)
                                    typeOfOperation = E_OperationType.doubleTouched;
                                state = E_ControlState.WaitingForFirstTouch;
                            }
                            if(touch.phase == TouchPhase.Moved)
                            {
                                maxmovecount +=1;
                            }
                            if(touch.phase == TouchPhase.Stationary)
                            {
                                timeOfFingerStay =Time.time - firstTouchTime;        //计算手指停留的时间
                                if(timeOfFingerStay >0.3 && (stateofmoving == E_MovingState.Continuous))    //如果手指停留超0.3秒,且处于持续行走状态,则立马静止
                                {
                                    stateofmoving = E_MovingState.SuddenlyStop;
                                    moving = false;
                                }
                            }
                            break;
                        }                            
                    }
                }
            }
        }
        
        

    }
View Code

  说完双击,咱们来说说滑动处理,其实滑动处理挺好处理的,就是读取touch.phase而已嘛,但是,要知道用户的操作都是有一定的噪声的,比如一些抖动之类的,底层的物理层帮我们处理的是细微的振动噪声和热噪声,而我们上层应用开发者需要处理的,就是人的操作噪声,比如说,我按住不放的时候,手抖了,这算是滑动还是按住不放的动作呢?也许你觉得这是一个不起眼的细节,然而对用户体验要求越来越高的现在,操作上的细节实际上就决定了一个游戏的成败,你的容错性较好,对细节处理的很好,那么将来游戏做好了,玩家玩得会比较舒服。假如你认为用户要来适应你得程序来进行操作适应的话,我想这个还是等你们的平台足够大了的时候再说吧。

  

原文地址:https://www.cnblogs.com/pengsy/p/4703585.html