在进行了一些搜索(谷歌搜索“统一移动检测点击”)后,我发现这是最热门的搜索结果。 @Mothil 的回答让我们非常接近解决方案,而 OP 的回答解决了这个问题。但是,OP的答案没有考虑多次点击。也不需要跟踪开始触摸、结束触摸和移动触摸的计数(例如int SCount, MCount, ECount)。
相反,我们可以像@mothil 那样直接循环每个触摸并通过其fingerId 跟踪每个单独的触摸。为此,我们需要两个数组来跟踪抽头的特性:1) 短时间延迟,以及 2) 无移动。在下面的数组中,数组索引是 fingerId。
private float[] timeTouchBegan;
private bool[] touchDidMove;
我们还需要一个变量来存储我们想要的点击时间阈值。在我的测试中,我发现0.2f 的阈值效果很好。
private float tapTimeThreshold = 0.2f;
在Start() 函数中,我们将初始化它以容纳10 个元素以进行10 次触摸。这可以修改为所需的触摸次数。
在Update() 函数中,我们循环遍历每个触摸。如果在TouchPhase.Began 中,那么我们将timeTouchBegan[fingerIndex] 设置为当前时间;我们还将touchDidMove[fingerIndex] 设置为false。
如果在TouchPhase.Moved 中,我们将touchDidMove[fingerIndex] 设置为true。
最后,在TouchPhase.Ended,我们可以计算点击时间。
float tapTime = Time.time - timeTouchBegan[fingerIndex];
如果点击时间小于阈值并且触摸没有移动,那么我们有一个经过验证的点击。
if (tapTime <= tapTimeThreshold && touchDidMove[fingerIndex] == false)
{
// Tap detected at touch.position
}
完整脚本
这是完整的课程:
public class TapManager : MonoBehaviour
{
private float[] timeTouchBegan;
private bool[] touchDidMove;
private float tapTimeThreshold = 0.2f;
void Start()
{
timeTouchBegan = new float[10];
touchDidMove = new bool[10];
}
private void Update()
{
// Touches
foreach (Touch touch in Input.touches)
{
int fingerIndex = touch.fingerId;
if (touch.phase == TouchPhase.Began)
{
Debug.Log("Finger #" + fingerIndex.ToString() + " entered!");
timeTouchBegan[fingerIndex] = Time.time;
touchDidMove[fingerIndex] = false;
}
if (touch.phase == TouchPhase.Moved)
{
Debug.Log("Finger #" + fingerIndex.ToString() + " moved!");
touchDidMove[fingerIndex] = true;
}
if (touch.phase == TouchPhase.Ended)
{
float tapTime = Time.time - timeTouchBegan[fingerIndex];
Debug.Log("Finger #" + fingerIndex.ToString() + " left. Tap time: " + tapTime.ToString());
if (tapTime <= tapTimeThreshold && touchDidMove[fingerIndex] == false)
{
Debug.Log("Finger #" + fingerIndex.ToString() + " TAP DETECTED at: " + touch.position.ToString());
}
}
}
}
}
统一测试
我使用 Unity Remote 在我的游戏中对此进行了测试。在下面的屏幕截图中,您可以看到我的调试控制台日志。我做了一个四指敲击。您可以看到手指 0 到 3 进入和离开时没有检测到任何移动。检测到每个手指的轻敲,并将每个轻敲的位置打印到控制台。