Unity如何实现触摸和鼠标操作的几个问题

**关键点1:**在unity中touch事件同时也会触发GetMouseButton事件,有时候可能会给你带来方便,但是如果没有意识到这个问题的话,也很可能给你带来很大的麻烦。

**关键点2:**触摸操作也可以使用Input.GetAxis(“MouseX”)(或"MouseY",下同,略去不写)来判断指尖移动的距离,虽然这点很方便,但是这样就带来了另外两个问题,见关键点3和4;

**关键点3:**Input.GetAxis(“MouseX”)取得的值与Input.GetTouch(0).deltaPosition的取值有一些细微但是很重要的差别:

    1)==**如果使用鼠标操作**==,那么Input.GetAxis对鼠标移动的取值方式表现的很正常,因为不管是否点击,鼠标始终存在,鼠标位置始终能够正常获取,Input.GetAxis("MouseX")原本是为鼠标设计的,取值方式是连续的;使用Input.GetTouch(0).deltaPosition无效,因为没有触摸操作;

    2)==**如果使用触摸操作**==,再细分两种情形:

              a. 如果使用if(Input.GetMouseButton(0))来作为判断是否按下的条件:

那么使用Input.GetAxis来获取手指的移动就需要注意了,触摸的手指是可以离开屏幕的,一旦手指离开屏幕,GetAxis(“MouseX”)就不知所措了,只好记住离开前的手指位置,下一次手指再接触的时候和这个位置对比(个人猜测GetAxis(“MouseX”)是对比鼠标/触摸点位置的方法来取得的)。例如手指从屏幕的左边拿开,然后再触摸屏幕的右边,那么取得的x位置会是一个很大的正值。这就是个很大的问题,这个问题是GetMouseButton和GetAxis在使用手指触摸的情况下配合上的不默契产生的。但是使用Input.GetTouch(0).deltaPosition就不会有这种现象,个人猜测可能是因为deltaPosition是测量每一帧内的移动距离的方法吧。

              b. 如果使用if(Input.touchCount>0&&Input.GetTouch(0).phase== TouchPhased.Moved)来做为判断是否按下的条件:

使用Input.GetAxis(“Mouse X”),没有任何问题;

使用deltaPosition同样没有任何问题,因为这就是为触摸操作而设计的。

关键点4:实践中发现在直观感觉差不多的滑动过程(分别用鼠标拖动和手指拖动)中,Input.GetTouch(0).deltaPosition.x的值总是比Input.GetAxis(“Mouse X”)取得的值要大很多,分析可能是手机屏幕dpi比较大的原因,因此在实践中为了获取直观感受差不多的旋转速度,要分别调试旋转加成系数。

总结一下:不要使用一条代码判断两种情况,最好分开,做一个单选(可以使用Enum),要么鼠标操作,要么触摸操作,分别使用最合适的判断和函数,并分别调试旋转加成系数

事件回顾:

在写一个惯性拖动旋转的脚本的时候,为在pc和Android平台上都能使用(即用鼠标和触摸都能控制),我使用了如下的判断语句:

if(Input.GetMouseButton(0) || (Input.touchCount>0&& Input.GetTouch(0).phase == TouchPhase.Moved)

来判断鼠标按下或者手指按下,并用Input.GetAxis(“MouseX”)来获取拖动的值,期望能够一次判断两种情况,分别适应不同平台的操作。在pc上使用鼠标操作没有任何问题,但是在android上触摸操作时出现了问题。经过多次测试并查阅资料,发现原来触摸操作也可以触发Input.GetMouseButton(0)的事件,这就引发了前述关键点3>2)>a 中的问题。

惯性旋转物体脚本:
 
usingUnityEngine;
 
usingSystem.Collections;
 
//操作方式
 
public enumControlType{
 
mouseControl,
 
touchControl,
 
}
 
public classRotateTarget: MonoBehaviour
 
{
 
publicControlType controlType;
 
   public Transform rotTarget;
 
 
//旋转速度加成系数
 
   public float rotSpeedScalar;
 
   private float currentSpeed = 0;
 
 
   void Update()
 
   {
 
       if(controlType==ControlType.mouseControl)
 
      {
 
          //鼠标操作
 
          if(Input.GetMouseButton(0))
 
          {
 
                //拖动时速度
 
  //鼠标或手指在该帧移动的距离*deltaTime为手指移动的速度,此处为Input.GetAxis("MouseX") / Time.deltaTime
 
  //不通帧率下lerp的第三个参数(即混合比例)也应根据帧率而不同--
 
  //考虑每秒2帧和每秒100帧的情况,如果此参数为固定值,那么在2帧的情况下,一秒后达到目标速度的0.75,而100帧的情况下,一秒后则基本约等于目标速度
 
                currentSpeed = Mathf.Lerp(currentSpeed, Input.GetAxis("Mouse X") /Time.deltaTime,0.5f*Time.deltaTime);
 
          } else
 
          {
 
             //放开时速度
 
             currentSpeed = Mathf.Lerp(currentSpeed, 0,0.5f*Time.deltaTime);
 
          }
 
      }
 
elseif(controlType==ControlType.touchControl)
 
      {
 
          //触摸操作
 
          if (Input.touchCount > 0&& Input.GetTouch(0).phase == TouchPhase.Moved)
 
          {
 
//在安卓设备上也可以用MouseX,根据实验,touch[0].deltaPosition.x的值总是比Mouse X的值大很多,所以此处使用MouseX
 
currentSpeed= Mathf.Lerp(currentSpeed, Input.GetAxis("MouseX")/Time.deltaTime,0.5f*Time.deltaTime);
 
          } else
 
          {
 
             //放开时速度
 
             currentSpeed = Mathf.Lerp(currentSpeed, 0,0.5f*Time.deltaTime);
 
          }
 
      }
 
      rotTarget.Rotate(Vector3.down, Time.deltaTime * currentSpeed *rotSpeedScalar);
 
   }
 
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值