Unity3d android開發之觸摸操做識別-雙擊,滑動去噪處理

  在android上開發unity遊戲,和在IOS上差很少,可是仍是有許多細微的差異的,這多是因爲系統或者硬件問題致使的差別吧,比較典型的就是-觸摸屏上實現雙擊的差異。html

  Unity3d 官方API文檔上告訴咱們一件事,http://docs.unity3d.com/Manual/MobileInput.html ,如圖android

  

  你看他說,IOS設備就能夠經過tapcontrol來判斷是否有雙擊產生,然而android設備並無這個功能。緣由無論,看到這裏咱們就知道了,要想判斷雙擊事件,還得靠本身手動寫代碼實現了。其實,模仿windows的鼠標雙擊機制,咱們徹底能夠利用已有的API對雙擊進行識別,好比單擊後,先不進行單擊操做,而是進行雙擊監測,監測0.1秒內是否又有新的觸摸手指觸摸到了屏幕,若是有,則認爲整個時間連起來算一個雙擊,而忽略前面的單擊,若是0.1秒過去,沒有任何新的響應,咱們就繼續處理0.1秒前的單擊時間,記得在進行雙擊監測前,保存下當初那一幀的數據,不然,0.1秒後,你再處理單擊事件的時候,就物是人非了。windows

  廢話很少說,直接上核心代碼圖ide

  

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而已嘛,可是,要知道用戶的操做都是有必定的噪聲的,好比一些抖動之類的,底層的物理層幫咱們處理的是細微的振動噪聲和熱噪聲,而咱們上層應用開發者須要處理的,就是人的操做噪聲,好比說,我按住不放的時候,手抖了,這算是滑動仍是按住不放的動做呢?也許你以爲這是一個不起眼的細節,然而對用戶體驗要求愈來愈高的如今,操做上的細節實際上就決定了一個遊戲的成敗,你的容錯性較好,對細節處理的很好,那麼未來遊戲作好了,玩家玩得會比較舒服。假如你認爲用戶要來適應你得程序來進行操做適應的話,我想這個仍是等大家的平臺足夠大了的時候再說吧。this

相關文章
相關標籤/搜索