Unity触控——单指、双指、Windows大屏多人触控

前段时间做了个Windows系统的大屏触控程序,最多同时支持十点触控,并且在各自的小窗口中要分别处理,即每个小窗口中的触点为一个处理组,判断其单点或多点操作。按以往移动端程序的触屏事件Input.GetTouch(int index)不满足需求,着实费了一番功夫。

首先分享常用的移动端触控方法,单指、双指操作。这里举例为单指操作模型旋转,双指同向移动操作模型平移,双指反向移动操作模型缩放。单指操作不再赘述,双指操作我选用向量判断。

    public void SingleTouch()
    {
        Debug.Log("SingleTouch");        
        if (Input.GetTouch(0).phase == TouchPhase.Began || !isSingleFinger)
        {
            //在开始触摸或者从两字手指放开回来的时候记录一下触摸的位置  
            preSingleTouchPosition = Input.GetTouch(0).position;
        }
        if (Input.GetTouch(0).phase == TouchPhase.Moved)
        {
            currentModel.transform.Rotate(Vector3.up, -Input.GetTouch(0).deltaPosition.x * 0.5f);            
            preSingleTouchPosition = Input.GetTouch(0).position;
        }
        isSingleFinger = true;

    }
    public void DoubleTouch()
    {
        Debug.Log("DoubleTouch:" + Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position));
        if (isSingleFinger)
        {
            oldPosition1 = Input.GetTouch(0).position;
            oldPosition2 = Input.GetTouch(1).position;
            beginTouchDistance = Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
            currentScale = currentModel.transform.localScale;
            currentPosition = currentModel.transform.localPosition;
        }

        if (Input.GetTouch(0).phase == TouchPhase.Moved && Input.GetTouch(1).phase == TouchPhase.Moved)
        {
            Vector2 xiangliang1 = Input.GetTouch(0).position - oldPosition1;
            Vector2 xiangliang2 = Input.GetTouch(1).position - oldPosition2;            
            float dir = Vector2.Dot(xiangliang1.normalized, xiangliang2.normalized);
            if (dir <= 1 && dir >= 0)
            {
                currentModel.transform.Translate(Input.GetTouch(0).deltaPosition.x * 0.01f, Input.GetTouch(1).deltaPosition.y * 0.01f, 0, Space.World);
            }
            else if (dir >= -1 && dir < 0)
            {
                float currentTouchDistance = Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
                float tmpScale = currentTouchDistance / beginTouchDistance - 1f;
                tmpScale += currentScale.x;
                tmpScale = Mathf.Clamp(tmpScale, 0.5f, 3f);
                currentModel.transform.localScale = Vector3.one * tmpScale;

            }
        }
        isSingleFinger = false;

    }

以上为移动端常用的触控方法,接下来简述一下Windows大屏触控。

首先来说,需求为在大屏上点击弹出小窗口,窗口中会有所点模型的操作,平移、旋转、缩放以及UI控制的动画等展示。因所选大屏最多支持十点触控,故限制小窗口最多生成5个,且每个小窗口需要独立操作,即在窗口1内的操作不会影响其他窗口或窗口外的点击事件,并且窗口1外的触控同样不影响窗口1内的操作。所以这里需要面向对象的概念,将触点作为对象,创建类。这里由于功能并不复杂,小窗口作为预制体生成,所以只需定义一个点击的窗口对应的UI控制组件和一个触点集合,就可以完成需求。

public class A
{
    public UIManager obj;//自定义UI控制脚本
    public List<Touch> touch = new List<Touch>();
}

然后实例这个类进行处理,这里我只判断了点在哪个窗口内,然后将窗口内所有点存入集合,方便在控制脚本里调用并响应相应的事件。

    public void ClickObject()
    {
        Debug.Log("ClickObject");
        a = new List<A>();
        for (int i = 0; i < Input.touchCount; i++)
        {
            eventDataCurrentPosition.position = Input.GetTouch(i).position;
            List<RaycastResult> results = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
            if(results.Count > 0)
            {
                if (results[0].gameObject.transform.parent.GetComponent<UIManager>() != null)
                {
                    if(a.Count == 0)
                    {
                        A a1 = new A();
                        a1.obj = results[0].gameObject.transform.parent.GetComponent<UIManager>();
                        a1.touch.Add(Input.GetTouch(i));
                        a.Add(a1);
                    }
                    else
                    {
                        int aa = a.Count;
                        for (int j = 0; j < aa; j++)
                        {
                            if(a[j].obj == results[0].gameObject.transform.parent.GetComponent<UIManager>())
                            {
                                a[j].touch.Add(Input.GetTouch(i));
                            }
                            else
                            {
                                A a1 = new A();
                                a1.obj = results[0].gameObject.transform.parent.GetComponent<UIManager>();
                                a1.touch.Add(Input.GetTouch(i));
                                a.Add(a1);
                            }
                        }
                    }
                }
            }
        }
        
    }

要注意,由于小窗口使用UI组件显示,因此需要先保证EventSystem的存在,PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current),否则窗口中的点击将无法触发,也就无法记录并进行后续操作。

对象类及分组处理已完成,接下来向单指、双指的触控方法中传参即可,需根据实际需求及应用环境进行处理,这里就不作过多描述。

 

  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值