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

实现Singleton后IPointerClickHandler无法触发的解决求助

解决IPointerClickHandler在单例模式下不触发的问题

先确认基础条件是否达标

Unity的UI/射线事件触发必须满足以下前提,先逐一排查:

  • 场景里必须有EventSystem对象(没有的话右键选「UI → Event System」手动创建)
  • 挂载PlaceTowers脚本的物体:
    • 若是UI元素:自带的Graphic组件(比如Image、Text)要开启Raycast Target(默认是勾选的,别手动关掉)
    • 若是非UI物体:必须添加Collider(3D场景)或Collider2D(2D场景),确保在相机的射线检测范围内

修复单例基类的错误逻辑

你当前的单例基类代码存在无限递归调用的致命问题:基类的OnPointerClick里调用PlaceTowers.i.OnPointerClick,而PlaceTowers继承自这个基类,会导致循环调用卡死,自然无法触发正常逻辑。

正确的单例基类(只负责单例逻辑)

单例基类别掺和事件接口的实现,专注做单例初始化:

public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;

    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<T>();
                // 找不到实例时自动创建(可选,按需开启)
                if (_instance == null)
                {
                    var singletonObj = new GameObject(typeof(T).Name);
                    _instance = singletonObj.AddComponent<T>();
                    DontDestroyOnLoad(singletonObj);
                }
            }
            return _instance;
        }
    }

    protected virtual void Awake()
    {
        // 确保单例唯一
        if (_instance == null)
        {
            _instance = this as T;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

子类正确实现事件接口

让PlaceTowers自己实现事件接口,保证方法是public且逻辑独立:

public class PlaceTowers : Singleton<PlaceTowers>, IPointerClickHandler, IPointerDownHandler, IPointerUpHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log("点击事件触发!");
        // 这里写你的业务逻辑
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        // 可选:鼠标按下时的逻辑
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        // 可选:鼠标抬起时的逻辑
    }
}

额外排查点

  • 检查物体层级:确保物体所在层级没有被EventSystem的射线检测忽略(看EventSystem的Standalone Input Module组件里的「Raycast Ignore Layer」)
  • 检查是否有其他脚本抢事件:比如物体上挂了EventTrigger组件,或者其他实现IPointerClickHandler的脚本,可能会拦截事件
  • 动态生成的物体:如果是代码生成的物体,要确保生成时正确添加了Collider/Graphic组件,且单例实例初始化正常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:20:28