Unity触摸输入:如何检测手指Pinch In(捏合)与Pinch Out(张开)
解决Unity触摸捏合的Pinch In/Out判断问题
你的核心问题在于帧间比例对比的逻辑容易受初始值干扰,且未正确处理触摸状态的持续与切换,下面是具体的修正方案:
关键问题分析
- 原代码中
prevtouchCount从未更新,导致prevtouchCount != 2的判断只会触发一次,后续手指持续触摸时无法正确维护状态 - 用
ratio(当前距离/初始距离)和previousRatio对比,容易因初始距离的基准值导致判断波动,我们需要的是相邻两帧的距离变化来直接判断捏合方向 - 未处理手指从2指切换到其他数量时的变量重置,会影响下一次捏合判断
修正后的代码
using UnityEngine; using UnityEngine.InputSystem.EnhancedTouch; using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch; public class DetectTouch : MonoBehaviour { // 上一帧的触摸数量 private int _prevTouchCount; // 初始两指距离(用于缩放计算) private float _initialPinchDistance; // 上一帧的两指距离(用于判断捏合方向) private float _lastPinchDistance; // 初始相机FOV private float _originalCameraFOV; private void OnEnable() { // 启用EnhancedTouch输入 EnhancedTouchSupport.Enable(); } private void OnDisable() { // 禁用EnhancedTouch,避免内存泄漏 EnhancedTouchSupport.Disable(); } void Update() { int currentTouchCount = Touch.activeFingers.Count; if (currentTouchCount == 2) { Touch touch1 = Touch.activeFingers[0].currentTouch; Touch touch2 = Touch.activeFingers[1].currentTouch; float currentDistance = Vector2.Distance(touch1.screenPosition, touch2.screenPosition); // 刚进入两指触摸状态,初始化基准值 if (_prevTouchCount != 2) { _initialPinchDistance = currentDistance; _lastPinchDistance = currentDistance; _originalCameraFOV = Camera.main.fieldOfView; } else { // 通过帧间距离变化判断捏合方向 if (currentDistance < _lastPinchDistance) { Debug.Log("Pinch In(手指靠近)"); } else if (currentDistance > _lastPinchDistance) { Debug.Log("Pinch Out(手指远离)"); } // 相等时不做处理,避免抖动 // 更新缩放逻辑(保留原有缩放功能) float ratio = currentDistance / _initialPinchDistance; Camera.main.fieldOfView = _originalCameraFOV / ratio; } // 更新上一帧的距离 _lastPinchDistance = currentDistance; } else { // 当触摸数量从2变为其他时,重置变量,避免影响下一次捏合 if (_prevTouchCount == 2) { _initialPinchDistance = 0; _lastPinchDistance = 0; } } // 必须更新上一帧的触摸数量,否则无法检测状态切换 _prevTouchCount = currentTouchCount; } }
核心改动说明
- 帧间距离对比:用
currentDistance和_lastPinchDistance直接对比,精准判断每帧的手指移动方向,避免比例带来的波动 - 状态切换处理:在触摸数量从2变为其他时重置变量,确保下次捏合的初始值正确;同时在刚进入2指状态时初始化所有基准值
- 输入系统生命周期管理:添加
OnEnable/OnDisable来管理EnhancedTouch的启用/禁用,符合Unity最佳实践 - 避免无效判断:当两帧距离相等时不输出日志,过滤微小抖动导致的误判
关于手指持续触摸的处理
只要保持_prevTouchCount的更新,以及在每帧维护_lastPinchDistance,即使用户始终不抬起手指,代码也能持续、稳定地判断捏合方向,同时正确执行缩放逻辑。
内容的提问来源于stack exchange,提问作者Saif
相关产品推荐
相关产品推荐

