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),否则窗口中的点击将无法触发,也就无法记录并进行后续操作。

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

 

  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
"Failed to load ApplicationContext"是一个常见的错误信息,通常在使用Spring框架进行应用程序开发时出现。它表示应用程序无法加载ApplicationContext,即无法加载Spring的配置文件和相关的bean定义。 这个错误可能有多种原因,包括但不限于以下几种情况: 1. 配置文件路径错误:请确保配置文件的路径是正确的,并且在类路径下可访问到。 2. 依赖项缺失:如果应用程序依赖于其他库或模块,而这些依赖项未正确配置或缺失,就会导致加载ApplicationContext失败。请检查项目的依赖项配置,并确保所有依赖项都已正确添加。 3. 配置文件格式错误:请确保配置文件的格式是正确的,没有语法错误或格式问题。可以使用Spring提供的工具来验证配置文件的正确性。 4. Bean定义错误:如果在配置文件中定义的bean存在问题,比如类名错误、属性设置错误等,也会导致加载ApplicationContext失败。请检查bean定义,并确保其正确性。 5. 环境配置问题:有时候,加载ApplicationContext失败可能与环境配置有关。比如数据库连接配置错误、网络连接问题等。请检查相关的环境配置,并确保其正确性。 以上是一些常见的导致"Failed to load ApplicationContext"错误的原因和解决方法。如果以上方法都无法解决问题,建议查看具体的错误日志或调试信息,以便更准确地定位问题所在。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值