Unity3D开发之判断鼠标是否在UI上

本文探讨了Unity中EventSystem的局限性,特别是在存在PhysicsRaycaster时,如何自定义射线检测方法以准确判断鼠标是否位于UI元素上。介绍了如何通过遍历所有GraphicRaycaster并检查射线结果来实现这一目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

unity给我们提供了一条api。

EventSystem.current.IsPointerOverGameObject()==true

他是利用unity的EventSystem事件系统判断射线是否射到物体上。我们查看官方文档可以看到继承BaseRaycaster的有三个组件,.PhysicsRaycaster, Physics2DRaycaster, GraphicRaycaster,所以当我们项目中只有canvas自带的GraphicRaycaster时,我们可以使用上述api判断鼠标是否在UI上。但是当我们场景camera上挂有PhysicsRaycaster,则判断完全会出现问题。我们会发现鼠标移动到含有collider的3D物体上以上API也会返回true。此时我们需要自己写一个射线检测的方法来判断是否在UI上。

我们可以将方法写在静态工具类里供全局调用。

    static List<GraphicRaycaster> graphicRays;

    private static List<GraphicRaycaster> graphicRaycasters
    {
        get
        {
            if(graphicRays == null)
            {
                graphicRays = GameObject.FindObjectsOfType<GraphicRaycaster>().ToList<GraphicRaycaster>();
            }
           
            return graphicRays;
        }
    }

    private static EventSystem eventSystem
    {
        get { return EventSystem.current; }
    }

    /// <summary>
    /// 是否在UI上
    /// </summary>
    /// <returns></returns>
    public static bool IsOnUIElement()
    {
        eventData = new PointerEventData(eventSystem);
        eventData.pressPosition = Input.mousePosition;
        eventData.position = Input.mousePosition;
        List<RaycastResult> list = new List<RaycastResult>();
        if (graphicRaycasters == null) return false;
        foreach (var graphicRaycaster in graphicRaycasters)
        {
            graphicRaycaster.Raycast(eventData, list);
            foreach (var temp in list)
            {
                if (temp.gameObject.layer.Equals(5)) return true;
            }
        }
        return false;
    }

注意这里要获取所有的canvas上的GraphicRaycaster。另外:当我们要动态生成新的canvas添加到场景时,我们要写一个方法来管理新增的canvas上绑定的GraphicRaycaster。每个canvas上的GraphicRaycaster只能检测到目录下的UI.一般出现在动态生成3D canvas情景。

/// <summary>
    /// 增加新的GraphicRaycaster
    /// </summary>
    /// <param name="item"></param>
    public void AddGraphicRaycaster(GraphicRaycaster item)
    {
        graphicRays.Add(item);
    }


    /// <summary>
    /// 移除GraphicRaycaster
    /// </summary>
    /// <param name="item"></param>
    public void RemoveGraphicRaycaster(GraphicRaycaster item)
    {
        if (graphicRays.Contains(item))
            graphicRays.Remove(item);
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值