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

如何使用Ray仅检测一次GameObject的点击事件

解决Unity点击事件重复检测的问题

首先明确你遇到重复检测的核心原因:大概率是这个脚本被挂载到了12个不同的GameObject上,导致每次点击时,每个脚本实例都会执行Update里的点击检测逻辑,因此输出12次日志。此外,被点击对象带有多个重叠Collider2D的可能性较低,因为你使用的Physics2D.Raycast只会返回最近的碰撞体。

以下是几种可行的解决方法:

方法1:确保脚本仅存在一个实例

  • 检查场景中所有对象,移除多余的该脚本挂载,只保留一个全局点击检测脚本(比如挂在Camera或空的Manager对象上)。
  • 或者用单例模式强制脚本只有一个实例,修改代码如下:
public class ClickDetector : MonoBehaviour
{
    public static ClickDetector Instance;

    void Awake()
    {
        // 确保全局只有一个实例
        if (Instance != null && Instance != this)
        {
            Destroy(this.gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(this.gameObject);
    }

    void Update()
    {
        if(Input.GetMouseButtonDown(0)){
            Debug.Log("Pressed left click, casting ray");
            CastRay();
        }   
    }

    protected void CastRay(){
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit2D hit = Physics2D.Raycast (ray.origin, ray.direction, Mathf.Infinity);
        if(hit){
            Debug.Log(hit.collider.gameObject.name);
        }
    }
}

方法2:使用Unity UI事件系统(推荐)

如果是给特定GameObject添加点击响应,更推荐用IPointerClickHandler接口,无需在Update里轮询,且每个对象只会响应自己的点击:

  1. 确保场景中有EventSystem对象(没有的话右键UI→EventSystem创建)。
  2. 给需要点击的GameObject添加Physics2DRaycaster组件(2D对象)或GraphicRaycaster组件(UI对象)。
  3. 修改脚本实现接口:
using UnityEngine.EventSystems;

public class ClickableObject : MonoBehaviour, IPointerClickHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        // 仅在点击当前对象时触发
        Debug.Log("Clicked on: " + gameObject.name);
    }
}

方法3:用静态变量全局控制点击状态

如果必须保留多个脚本实例,可以用静态布尔变量全局锁定点击状态,避免重复触发:

public class ClickDetector : MonoBehaviour
{
    private static bool isClickHandled = false;

    void Update()
    {
        if(Input.GetMouseButtonDown(0)){
            if (isClickHandled) return;
            isClickHandled = true;
            Debug.Log("Pressed left click, casting ray");
            CastRay();
        }

        // 松开鼠标时重置状态,允许下次点击
        if(Input.GetMouseButtonUp(0)){
            isClickHandled = false;
        }
    }

    protected void CastRay(){
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit2D hit = Physics2D.Raycast (ray.origin, ray.direction, Mathf.Infinity);
        if(hit){
            Debug.Log(hit.collider.gameObject.name);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:33:19