修复Unity中的ScrollRect多点触控?

时间:2019-05-20 12:32:32

标签: c# android ios unity3d

当前,ScrollRect涉及到移动设备上的多点触控。

如果您自己尝试一下,您会发现,只要将两根手指放在屏幕上,内容就会跳来跳去,并产生一些意想不到的行为。

有什么解决办法吗?目前,this是我找到的唯一解决方案,但在某些情况下仍然存在问题,而且最重要的是,它无法确定屏幕上所有手指的平均输入位置(或MultiTouchPosition

这是我从MultiTouchScrollRect.cs位桶中对UnityUIExtensions脚本进行的修改,但是每次我将下一根手指放在屏幕上时,它都会跳转:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class MultiTouchScrollRect : ScrollRect
{
    private int minimumTouchCount = 1, maximumTouchCount = 2, pointerId = -100;

    public Vector2 MultiTouchPosition
    {
        get
        {
            Vector2 position = Vector2.zero;
            for (int i = 0; i < Input.touchCount && i < maximumTouchCount; i++)
            {
                position += Input.touches[i].position;
            }
            position /= ((Input.touchCount <= maximumTouchCount) ? Input.touchCount : maximumTouchCount);
            return position;
        }
    }

    public override void OnBeginDrag(PointerEventData eventData)
    {
        if (Input.touchCount >= minimumTouchCount)
        {
            pointerId = eventData.pointerId;
            eventData.position = MultiTouchPosition;
            base.OnBeginDrag(eventData);
        }
    }
    public override void OnDrag(PointerEventData eventData)
    {
        if (Input.touchCount >= minimumTouchCount)
        {
            eventData.position = MultiTouchPosition;
            if (pointerId == eventData.pointerId)
            {
                base.OnDrag(eventData);
            }
        }
    }
    public override void OnEndDrag(PointerEventData eventData)
    {
        if (Input.touchCount >= minimumTouchCount)
        {
            pointerId = -100;
            eventData.position = MultiTouchPosition;
            base.OnEndDrag(eventData);
        }
    }
}

感谢您的时间!

2 个答案:

答案 0 :(得分:0)

尝试一下(尚未测试):

public Vector2 MultiTouchPosition
{
    get
    {
        int nTouches = ((Input.touchCount <= maximumTouchCount) ? Input.touchCount : maximumTouchCount);
        if(nTouches == 1)
        {
             return Input.touches[0].position;
        } 
        else 
        {
             return Vector2.Lerp(Input.touches[0].position, Input.touches[1].position, 0.5f); //middle point between them
        }
    }
 }

由于您要处理的触摸量只能是一两个,因此更好地处理每种情况都不同。

我不知道您为什么尝试分割位置,位置是Vector2,您需要计算它们之间的中间点,可以使用Vector2.Lerp(0.5f确定您想要中间点)来完成

答案 1 :(得分:0)

对于那些感兴趣的人,这是我编写的扩展ScrollRect类,它可以解决该问题:

// Build this data structure in the class constructor (not shown here)
List<Dictionary<String, String>> planningData = null;

// planningDataKeys.Count is always same as planningDataValues.Count
public List<Dictionary<String, String>> GetPlanningDataMatching_alt(List<String> planningDataKeys, List<String> planningDataValues)
{
    IEnumerable<Dictionary<String, String>> matchingPlanningData = null;
    for (int inx = 0; inx < planningDataKeys.Count; ++inx)
        matchingPlanningData = (inx == 0 ? planningData : matchingPlanningData)
                                        .Where(row => row[planningDataKeys[inx]] == planningDataValues[inx]);
    return matchingPlanningData.ToList();
}

// planningDataKeys.Count is always same as planningDataValues.Count
public List<Dictionary<String, String>> GetPlanningDataMatching(List<String> planningDataKeys, List<String> planningDataValues)
{
    List<Dictionary<String, String>> matchingPlanningData = null;
    for (int inx = 0; inx < planningDataKeys.Count; ++inx)
        matchingPlanningData = (inx == 0 ? planningData : matchingPlanningData)
                                        .Where(row => row[planningDataKeys[inx]] == planningDataValues[inx])
                                        .ToList();
    return matchingPlanningData;
}