You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity:按压状态下鼠标/手指划过Sprite检测方案及代码问题求助

解决按住鼠标/手指划过Sprite时触发事件的问题

你之前的实现有两个核心问题:一是用3D射线检测处理2D Sprite,导致命中逻辑失效;二是误用了仅检测按下瞬间的Input.GetMouseButtonDown(0),而非持续按住的状态检测。下面给你两种针对性的解决方案:

方案一:按住时划过Sprite仅触发一次(进入时执行操作)

适合“按住后移动到Sprite上就完成一次操作”的场景,比如你需求里隐藏物体的逻辑:

public class Hand : MonoBehaviour {
    // 标记本次按住过程中是否已触发过事件,避免重复执行
    private bool _hasTriggeredDuringHold = false;

    private void Update() {
        // 检测鼠标左键/手指是否处于持续按住状态
        if (Input.GetMouseButton(0)) {
            // 将屏幕坐标转换为2D世界坐标,用于射线检测
            Vector2 worldMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            // 发射2D射线(方向不影响,仅检测当前位置的碰撞体)
            RaycastHit2D hit = Physics2D.Raycast(worldMousePos, Vector2.zero);

            // 检查射线是否命中当前Sprite的碰撞体
            if (hit.collider != null && hit.collider.gameObject == gameObject) {
                if (!_hasTriggeredDuringHold) {
                    // 执行你的目标逻辑,比如隐藏物体
                    gameObject.SetActive(false);
                    _hasTriggeredDuringHold = true;
                }
            } else {
                // 鼠标离开Sprite时重置标记,下次进入可重新触发
                _hasTriggeredDuringHold = false;
            }
        } else {
            // 松开鼠标时重置标记,为下一次按住操作做准备
            _hasTriggeredDuringHold = false;
        }
    }
}

方案二:按住期间只要在Sprite上就持续触发

如果需要按住时在Sprite上移动的全程都执行逻辑(比如持续更新状态或播放动画),可以简化代码去掉触发标记:

public class Hand : MonoBehaviour {
    private void Update() {
        if (Input.GetMouseButton(0)) {
            Vector2 worldMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            RaycastHit2D hit = Physics2D.Raycast(worldMousePos, Vector2.zero);

            if (hit.collider != null && hit.collider.gameObject == gameObject) {
                // 这里写你需要持续执行的逻辑
                Debug.Log("按住并停留在Sprite上");
            }
        }
    }
}

关键注意事项

  • 给Sprite添加2D碰撞体:必须给你的Sprite组件添加BoxCollider2D(或其他2D碰撞体)并启用,这是射线检测能命中的前提。
  • 切换到2D物理检测:之前你用的Physics.Raycast是3D射线,Sprite属于2D对象,必须用Physics2D.Raycast才能正确检测碰撞。
  • 区分输入检测方法:Input.GetMouseButton(0)检测的是持续按住状态,而Input.GetMouseButtonDown(0)仅在按下的第一帧触发——这正是你之前代码无法满足需求的核心原因。

内容的提问来源于stack exchange,提问作者Keith Power

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:43:55