Unity3D Android开发之触摸操作识别——单击/双击简单区分两种触屏方式

本人是自学的,可能逻辑不够清晰,如有误,欢迎交流。

需求

需要区分左右手操作,有2种手势,假设红色为左手(单击),蓝色为右手(双击),并且一直跟踪区别左右手。然后其他根据左右手的具体操作,可在别的脚本通过调用该getTouch()即可。具体看下动图。

效果图

这里写图片描述

这里写图片描述

知识点

1、Input.getTouch(int index):按索引值获取一个Touch对象。

2、Touch.fingerId:特定的触摸,会持续下去,它是一个唯一的标识符,可用此跟踪任何触摸操作。当触摸从阵列中消失时,触摸将结束,此ID将用于另一次触摸

3、解释2、
①将手指按食指、中指、无名指、小指的顺序触摸屏幕 :
食指触摸后,fingerID=0;
中指触摸后,fingerID=1;
无名触摸后,fingerID=2;
小指触摸后,fingerID=3;
②之后中指离开屏幕:
食指还是fingerID=0;
无名指还是fingerID=2;
小指还是fingerID=3;
③这时又有一个手指触摸屏幕上:(不一定是中指)
食指还是fingerID=0
无名指还是fingerID=2;
小指还是fingerID=3;
新手指触摸后,fingerID=1;
新手指加入时,看到fingerID=1是空,就直接占用fingerID。后面再加新手指,就fingerID=4。

4.之前没搞清楚fingerID和getTouch()的参数间的关系,时不时出现bug,然后做了一些测试,如下图。
黑色字是我触碰操作,蓝色字是测试得的。
sakura

代码

	public GameObject mouse_L, mouse_R;
    public int z = 9;   //鼠标离摄像机的z轴距离
    public Touch touch_L, touch_R;


    void Start()
    {
        //初始化左右touch为结束阶段(没触碰点)
        touch_L = new Touch();
        touch_L.phase = TouchPhase.Canceled;
        touch_R = new Touch();
        touch_R.phase = TouchPhase.Canceled;
    }

    void FixedUpdate()
    {
        //没有触碰点
        if (Input.touchCount == 0)
        {
            touch_L.phase = TouchPhase.Canceled;
            touch_R.phase = TouchPhase.Canceled;
            touch_L.fingerId = 0;
            touch_R.fingerId = 0;
        }
        //只有1触碰点
        else if (Input.touchCount == 1)
        {
            //刚触碰
            if (!IsTouch(touch_L) && !IsTouch(touch_R))
            {
                Debug.Log("ceshi:" + Input.GetTouch(0).tapCount);
                //多击/双击:右手
                if (Input.GetTouch(0).tapCount > 1)
                {
                    CreatTouch(0, "R"); //获取第1个触摸点默认右手(fingerID=0) 
                    touch_L.fingerId = 1;   //则第2个触摸点默认为左手(fingerID=1)
                    //Debug.Log("ceshi1:L ID:" + touch_L.fingerId + ",R ID:" + touch_R.fingerId + " ,touchCount" + Input.touchCount);
                }
                //单击:左手
                else
                {
                    CreatTouch(0, "L"); //获取第1个触摸点默认左手(fingerID=0) 
                    touch_R.fingerId = 1;   //则第2个触摸点默认为右手(fingerID=1
                }
            }
            else
            {
                if (Input.GetTouch(0).fingerId == touch_L.fingerId)
                {
                    CreatTouch(0, "L");
                }
                else if (Input.GetTouch(0).fingerId == touch_R.fingerId)
                {
                    CreatTouch(0, "R");
                }
                else
                {
                    Debug.Log("ceshi4:0 ID:" + Input.GetTouch(0).fingerId + ",phase:" +Input.GetTouch(0).phase);
                    Debug.Log("ceshi4:L ID:" + touch_L.fingerId + ",phase:" + touch_L.phase + ",R ID:" + touch_R.fingerId + ",phase:" + touch_R.phase + " ,touchCount" + Input.touchCount);
                }

            }
        }
        //2触碰点
        else if (Input.touchCount == 2)
        {
            CreatTouch(touch_L.fingerId, "L");
            CreatTouch(touch_R.fingerId, "R");

        }
    }
    
    bool IsTouch(Touch touch)
    {
        //当属于取消或结束,则没有触碰点
        if (touch.phase == TouchPhase.Canceled || touch.phase == TouchPhase.Ended)
            return false;
        return true;
    }

    //创建左/右手鼠标
    void CreatTouch(int i, string LorR)
    {
        if (LorR.Equals("L"))
        {
            touch_L = Input.GetTouch(i);  //获取第一个触摸点(默认左手)
            Vector3 touchPos_L = touch_L.position;  //获取左手坐标
            Vector3 pos_L = Camera.main.ScreenToWorldPoint(touchPos_L + new Vector3(0, 0, z));    //左触摸点的位置(相机屏幕坐标2d->3d + z轴偏移量)
            mouse_L.transform.position = pos_L; //左手触摸点的拖尾效果
        }
        else if (LorR.Equals("R"))
        {
            touch_R = Input.GetTouch(i);  //获取第二个触摸点(默认右手)
            Vector3 touchPos_R = touch_R.position;  //获取右手坐标
            Vector3 pos_R = Camera.main.ScreenToWorldPoint(touchPos_R + new Vector3(0, 0, z));//右触摸点的位置(相机屏幕坐标2d->3d + z轴偏移量)
            mouse_R.transform.position = pos_R; //右手触摸点的拖尾效果
        }
    }
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio 中,可以使用 `View.OnTouchListener` 接口来监听视图的触摸事件,然后根据触摸事件的类型来实现双击单击触摸和滑动等效果。 以下是一个示例代码,演示了如何实现一个具有双击单击触摸和滑动效果的按钮: ```java public class MyButton extends Button implements View.OnTouchListener { private static final long DOUBLE_CLICK_TIME_DELTA = 300; // 双击间隔时间阈值,单位毫秒 private long lastClickTime = 0; // 上一次单击的时间 private float startX = 0; // 触摸起始点的 x 坐标 private float startY = 0; // 触摸起始点的 y 坐标 public MyButton(Context context) { super(context); init(); } public MyButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 记录触摸起始点的坐标 startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_UP: long clickTime = System.currentTimeMillis(); // 判断是否双击 if (clickTime - lastClickTime < DOUBLE_CLICK_TIME_DELTA) { onDoubleClick(); } // 判断是否单击 else if (Math.abs(event.getX() - startX) < 10 && Math.abs(event.getY() - startY) < 10) { onClick(); } lastClickTime = clickTime; break; case MotionEvent.ACTION_MOVE: // 判断是否滑动 if (Math.abs(event.getX() - startX) > 10 || Math.abs(event.getY() - startY) > 10) { onSwipe(); } break; case MotionEvent.ACTION_CANCEL: break; } return false; } private void onDoubleClick() { // 双击事件处理 Toast.makeText(getContext(), "Double Clicked", Toast.LENGTH_SHORT).show(); } private void onClick() { // 单击事件处理 Toast.makeText(getContext(), "Clicked", Toast.LENGTH_SHORT).show(); } private void onSwipe() { // 滑动事件处理 Toast.makeText(getContext(), "Swiped", Toast.LENGTH_SHORT).show(); } } ``` 在上面的代码中,`MyButton` 继承自 `Button`,并实现了 `View.OnTouchListener` 接口。在 `init()` 方法中,将 `MyButton` 的触摸事件监听器设置为 `this`,即 `MyButton` 自身。 在 `onTouch()` 方法中,根据触摸事件的类型来判断双击单击触摸还是滑动,并分别调用 `onDoubleClick()`、`onClick()`、`onSwipe()` 方法进行处理。其中,在判断是否双击单击时,使用 `lastClickTime` 来记录上一次单击的时间,以便计算两次单击之间的时间差。 最后,在各个事件处理方法中,可以根据需要进行相应的处理,例如弹出提示框、执行动画等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值