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