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

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM