Unity中单点和多点触控

Input.touchCount获取当前的触摸点数目,若为1则是单点触控,大于1则是多点触控

点击事件用:Input.GetTouch(num).phase== TouchPhase.Began这样的格式:

1. usingUnityEngine;

2.  

3. usingSystem.Collections;

4.  

5. public classclick2 : MonoBehaviour {

6.  

7. //设置点击时显示的图片

8.  

9. public Texture2Dimg;

10. 

11.void Start () {

12. 

13.}

14. 

15.void Update () {

16. 

17.}

18. 

19.void OnGUI () {

20. 

21.//记录当前触控点数目

22. 

23.int count =Input.touchCount;

24. 

25.//单点触控,首个触控点的标志是0

26. 

27.if (count == 1){

28. 

29.//if(Input.GetTouch(0).phase== TouchPhase.Began){}

30. 

31.float x =Input.GetTouch(0).position.x;

32. 

33.float y =Input.GetTouch(0).position.y;

34. 

35.GUI.DrawTexture(newRect(x,y,100,100),img);

36. 

37.}

38. 

39.//多点触控,遍历每个触摸点

40. 

41.for (int i = 0 ;i < count ; i++){

42. 

43.//if(Input.GetTouch(i).phase== TouchPhase.Began){}

44. 

45.float x =Input.GetTouch(i).position.x;

46. 

47.float y =Input.GetTouch(i).position.y;

48. 

49.GUI.DrawTexture(newRect(x,y,100,100),img);

50. 

51.}

52. 

53.}

54. 

55.}

注意:

记得把脚本文件拖到Camera里面

然后设置脚本的图片

 



//======================================

关键点1:在unity中touch事件同时也会触发GetMouseButton事件,有时候可能会给你带来方便,但是如果没有意识到这个问题的话,也很可能给你带来很大的麻烦。
关键点2:触摸操作也可以使用Input.GetAxis("Mouse X")(或"Mouse Y",下同,略去不写)来判断指尖移动的距离,虽然这点很方便,但是这样就带来了另外两个问题,见关键点3和4;
关键点3:Input.GetAxis("Mouse X")取得的值与Input.GetTouch(0).deltaPosition的取值有一些细微但是很重要的差别:
 
         1) 如果使用鼠标操作,那么Input.GetAxis对鼠标移动的取值方式表现的很正常,因为不管是否点击,鼠标始终存在,鼠标位置始终能够正常获取,Input.GetAxis("Mouse X")原本是为鼠标设计的,取值方式是连续的;使用Input.GetTouch(0).deltaPosition无效,因为没有触摸操作;
         2)如果使用触摸操作,再细分两种情形:
                   a. 如果使用if(Input.GetMouseButton(0))来作为判断是否按下的条件:
    那么使用Input.GetAxis来获取手指的移动就需要注意了,触摸的手指是可以离开屏幕的,一旦手指离开屏幕,GetAxis("Mouse X")就不知所措了,只好记住离开前的手指位置,下一次手指再接触的时候和这个位置对比(个人猜测GetAxis("Mouse X")是对比鼠标/触摸点位置的方法来取得的)。例如手指从屏幕的左边拿开,然后再触摸屏幕的右边,那么取得的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(“Mouse X”)来获取拖动的值,期望能够一次判断两种情况,分别适应不同平台的操作。在pc上使用鼠标操作没有任何问题,但是在android上触摸操作时出现了问题。经过多次测试并查阅资料,发现原来触摸操作也可以触发Input.GetMouseButton(0)的事件,这就引发了前述 关键点3>2)>a 中的问题。


惯性旋转物体脚本:
using UnityEngine;
using System.Collections;
//操作方式
public enum ControlType{
mouseControl,
touchControl,
}
public class RotateTarget: MonoBehaviour
{
public ControlType controlType;
    public Transform rotTarget;


//旋转速度加成系数
    public float rotSpeedScalar;
    private float currentSpeed = 0;


    void Update()
    {
        if (controlType==ControlType.mouseControl)
        {
            //鼠标操作
            if (Input.GetMouseButton(0))
            {
                    //拖动时速度
   //鼠标或手指在该帧移动的距离*deltaTime为手指移动的速度,此处为Input.GetAxis("Mouse X") / 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);
            }
        }
else if(controlType==ControlType.touchControl)
        {
            //触摸操作
            if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
            {
//在安卓设备上也可以用Mouse X,根据实验,touch[0].deltaPosition.x的值总是比Mouse X的值大很多,所以此处使用Mouse X
currentSpeed = Mathf.Lerp(currentSpeed, Input.GetAxis("Mouse X")/Time.deltaTime,0.5f*Time.deltaTime);
            } else
            {
                //放开时速度
                currentSpeed = Mathf.Lerp(currentSpeed, 0, 0.5f*Time.deltaTime);
            }
        }
        rotTarget.Rotate(Vector3.down, Time.deltaTime * currentSpeed * rotSpeedScalar);
    }

}


//==========多点触控==============

//用于绑定参照物对象  
var target : Transform;  
//缩放系数  
var distance = 10.0;  
//左右滑动移动速度  
var xSpeed = 250.0;  
var ySpeed = 120.0;  
//缩放限制系数  
var yMinLimit = -20;  
var yMaxLimit = 80;  
//摄像头的位置  
var x = 0.0;  
var y = 0.0;  
//记录上一次手机触摸位置判断用户是在左放大还是缩小手势  
private var oldPosition1 : Vector2;  
private var oldPosition2 : Vector2;  
  
//初始化游戏信息设置  
function Start () {  
    var angles = transform.eulerAngles;  
    x = angles.y;  
    y = angles.x;  
  
    // Make the rigid body not change rotation  
    if (rigidbody)  
        rigidbody.freezeRotation = true;  
}  
  
function Update ()  
{  
    //判断触摸数量为单点触摸  
    if(Input.touchCount == 1)  
    {  
        //触摸类型为移动触摸  
        if(Input.GetTouch(0).phase==TouchPhase.Moved)  
        {  
            //根据触摸点计算X与Y位置  
            x += Input.GetAxis("Mouse X") * xSpeed * 0.02;  
            y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;  
  
        }  
    }  
  
    //判断触摸数量为多点触摸  
    if(Input.touchCount >1 )  
    {  
        //前两只手指触摸类型都为移动触摸  
        if(Input.GetTouch(0).phase==TouchPhase.Moved¦¦Input.GetTouch(1).phase==TouchPhase.Moved)  
        {  
                //计算出当前两点触摸点的位置  
                var tempPosition1 = Input.GetTouch(0).position;  
                var tempPosition2 = Input.GetTouch(1).position;  
                //函数返回真为放大,返回假为缩小  
                if(isEnlarge(oldPosition1,oldPosition2,tempPosition1,tempPosition2))  
                {  
                    //放大系数超过3以后不允许继续放大  
                    //这里的数据是根据我项目中的模型而调节的,大家可以自己任意修改  
                    if(distance > 3)  
                    {  
                        distance -= 0.5;  
                    }  
                }else  
                {  
                    //缩小洗漱返回18.5后不允许继续缩小  
                    //这里的数据是根据我项目中的模型而调节的,大家可以自己任意修改  
                    if(distance < 18.5)  
                    {  
                        distance += 0.5;  
                    }  
                }  
            //备份上一次触摸点的位置,用于对比  
            oldPosition1=tempPosition1;  
            oldPosition2=tempPosition2;  
        }  
    }  
}  
  
//函数返回真为放大,返回假为缩小  
function isEnlarge(oP1 : Vector2,oP2 : Vector2,nP1 : Vector2,nP2 : Vector2) : boolean  
{  
    //函数传入上一次触摸两点的位置与本次触摸两点的位置计算出用户的手势  
    var leng1 =Mathf.Sqrt((oP1.x-oP2.x)*(oP1.x-oP2.x)+(oP1.y-oP2.y)*(oP1.y-oP2.y));  
    var leng2 =Mathf.Sqrt((nP1.x-nP2.x)*(nP1.x-nP2.x)+(nP1.y-nP2.y)*(nP1.y-nP2.y));  
    if(leng1<leng2)  
    {  
         //放大手势  
         return true;  
    }else  
    {  
        //缩小手势  
        return false;  
    }  
}  
  
//Update方法一旦调用结束以后进入这里算出重置摄像机的位置  
function LateUpdate () {  
  
    //target为我们绑定的箱子变量,缩放旋转的参照物  
    if (target) {         
  
        //重置摄像机的位置  
        y = ClampAngle(y, yMinLimit, yMaxLimit);  
        var rotation = Quaternion.Euler(y, x, 0);  
        var position = rotation * Vector3(0.0, 0.0, -distance) + target.position;  
  
        transform.rotation = rotation;  
        transform.position = position;  
    }  
}  
  
static function ClampAngle (angle : float, min : float, max : float) {  
    if (angle < -360)  
        angle += 360;  
    if (angle > 360)  
        angle -= 360;  
    return Mathf.Clamp (angle, min, max);  
}  

猜你喜欢

转载自blog.csdn.net/qq_34444468/article/details/80520215