点击2D物体的时候,会点击到3D物体,一起被触发

#灵光一闪  #学习笔记记录 

点击2D物体时,会透过2D点击到3D物体,一起被触发  。当时遇见这个问题的时候 ,尝试过很多拦截的方法都没有成功,最后是通过物体管理+碰撞体管理 来实现解决的。

最近偶然突发灵感找到了一个解决方法:

简单来说就是当检测到点击的是2D物体,就截停 不再去检测3D物体,检测2D的层级比2D更高;

我这个拦截的只是当前脚本实现的射线检测,大量使用射线检测也会比较消耗性能,要减少性能消耗那就还是做好物体管理更简单,或者是做好射线检测管理也可以

但是如果你直接再物体上挂载 OnMouseDown();来执行还是会被检测到执行的 ;

这篇文章就当一个我的学习记录,如果有问题的话请大佬们指正,有更好的方法也可以分享一下

1、检测点击2D UI部分

点击到UI 部分就返回一个布尔值 或者返回点击到的 2D元素

    /// <summary>  
    /// 这个方法检测的是鼠标点击或触摸释放的事件
    /// 鼠标点击或触摸按下是否在UI GameObject上
    /// </summary>  
    public static bool IsClickDownOverUI()//using UnityEngine.EventSystems; 
    {
        if (Input.GetMouseButtonDown(0) || (Input.touchCount > 0 && Input.GetTouch(0).phase == UnityEngine.TouchPhase.Began))
        {
            //封装与指针(如鼠标或触摸屏上的手指)相关的事件数据的类
            PointerEventData eventData = new PointerEventData(EventSystem.current);
            // 在编辑器或触摸设备中,使用触摸ID(如果有的话)  
            eventData.position = (Input.touchCount > 0) ? Input.GetTouch(0).position : new Vector2(Input.mousePosition.x, Input.mousePosition.y);

            // 检查指针是否在UI GameObject上  ,存储所有被击中的 UI 元素的信息
            var results = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventData, results);
            return results.Count > 0;
        }

        return false;
    }

    /// <summary>  
    /// 这个方法检测的是鼠标点击或触摸释放的事件
    /// 鼠标点击或触摸释放是否在UI GameObject上。  
    /// </summary>  
    public static bool IsClickUpOverUI()
    {
        if (Input.GetMouseButtonUp(0) || (Input.touchCount > 0 && (Input.GetTouch(0).phase == UnityEngine.TouchPhase.Ended || Input.GetTouch(0).phase == UnityEngine.TouchPhase.Canceled)))
        {
            //封装与指针(如鼠标或触摸屏上的手指)相关的事件数据的类
            PointerEventData eventData = new PointerEventData(EventSystem.current);
            //输入类型(触摸或鼠标)来设置 PointerEventData 实例的 position 属性
            eventData.position = (Input.touchCount > 0) ? Input.GetTouch(0).position : new Vector2(Input.mousePosition.x, Input.mousePosition.y);
            //存储所有被击中的 UI 元素的信息
            var results = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventData, results);
            return results.Count > 0;
        }

        return false;
    }

2、检测到返回的Bool 值 进行 是否执行下面的操作

将完整代码就放在下面,如果点击到3D 物体就返回点击到的 Gameobject,根据Gameobject就可以执行相应的操作(也可以直接拿到物体上的组件/脚本执行对应值) 可做参考

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.EventSystems;

public class Radiographic_Inspection_Bool //: MonoBehaviour
{
    //检测鼠标点击和松开 2D UI,返回Bool 值

    /// <summary>  
    /// 这个方法检测的是鼠标点击或触摸释放的事件
    /// 鼠标点击或触摸按下是否在UI GameObject上
    /// </summary>  
    public static bool IsClickDownOverUI()//using UnityEngine.EventSystems; 
    {
        if (Input.GetMouseButtonDown(0) || (Input.touchCount > 0 && Input.GetTouch(0).phase == UnityEngine.TouchPhase.Began))
        {
            //封装与指针(如鼠标或触摸屏上的手指)相关的事件数据的类
            PointerEventData eventData = new PointerEventData(EventSystem.current);
            // 在编辑器或触摸设备中,使用触摸ID(如果有的话)  
            eventData.position = (Input.touchCount > 0) ? Input.GetTouch(0).position : new Vector2(Input.mousePosition.x, Input.mousePosition.y);

            // 检查指针是否在UI GameObject上  ,存储所有被击中的 UI 元素的信息
            var results = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventData, results);
            return results.Count > 0;
        }

        return false;
    }

    /// <summary>  
    /// 这个方法检测的是鼠标点击或触摸释放的事件
    /// 鼠标点击或触摸释放是否在UI GameObject上。  
    /// </summary>  
    public static bool IsClickUpOverUI()
    {
        if (Input.GetMouseButtonUp(0) || (Input.touchCount > 0 && (Input.GetTouch(0).phase == UnityEngine.TouchPhase.Ended || Input.GetTouch(0).phase == UnityEngine.TouchPhase.Canceled)))
        {
            //封装与指针(如鼠标或触摸屏上的手指)相关的事件数据的类
            PointerEventData eventData = new PointerEventData(EventSystem.current);
            //输入类型(触摸或鼠标)来设置 PointerEventData 实例的 position 属性
            eventData.position = (Input.touchCount > 0) ? Input.GetTouch(0).position : new Vector2(Input.mousePosition.x, Input.mousePosition.y);
            //存储所有被击中的 UI 元素的信息
            var results = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventData, results);
            return results.Count > 0;
        }

        return false;
    }

    #region 射线检测代码  

    /// <summary>
    /// 射线检测 返回点击到的物体
    /// </summary>
    /// <param name="GuideRail_Data.Main_Camera"></param>
    public static GameObject Ray_Detection(Camera Main_Camera)
    {
        GameObject Fqy = null;

        //中断
        if (Radiographic_Inspection_Bool.IsClickDownOverUI() == true)//拦截如果点击了2D ,就点击不到3D
        {
            //Debug.Log("中断,当前点击了2D 无法点击3D");
            return Fqy;
        }

        // 检测鼠标左键点击
        if (Input.GetMouseButtonDown(0))
        {
            // 发射一条射线从摄像机的位置向鼠标点击位置
            Ray ray = Main_Camera.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            // 如果射线击中了物体
            if (Physics.Raycast(ray, out hit))
            {
                // 获取击中的物体
                Fqy = hit.collider.gameObject;
                 //                Debug.Log("点击物体:" + Fqy.name);
                // if (Fqy.GetComponent<ImageManagement_2D_Message>() == null)//物体上没有对应的组件
                // {
                //     Fqy = null;
                //     return Fqy;
                // }
                return Fqy;
            }
        }

        return Fqy;
    }
    #endregion
}

直接调用函数即可,2D的操作可正常添加,3D部分就使用返回的GameObject物体执行相应的操作,如果觉得麻烦的话,可以就使用 OnMouseDown(); 做好物体管理即可!!!

有问题欢迎大家提出,一起学习进步!!!感谢!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值