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