#灵光一闪 #学习笔记记录
点击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(); 做好物体管理即可!!!
有问题欢迎大家提出,一起学习进步!!!感谢!!!