本来我是用 EventSystem.current.IsPointerOverGameObject()来检测是否点击在UI上的,但是发现,他对我的碰撞体也是返回ture,研究半天。。。。找不出问题,然后发现我的相机上挂载了PhysicsRaycaster,去掉之后就好了,至于为什么相机上挂载PhysicsRaycaster,好像是我的别的同事做的一个物体拖拽,用了 IDragHandler, IBeginDragHandler, IEndDragHandler,来做对3D物体的拖拽。。。我真的是无语。。。他的代码是这样的。。。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using QFramework;
public class ObjDrag : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{
private Vector3 ObjVector3 = Vector3.zero;
public string deskTag = "desk";
private Collider collider;
/// <summary>
/// isDrag等于false无法交互
/// </summary>
public bool isDrag = false;
void Start()
{
collider = GetComponent<Collider>();
}
public void OnBeginDrag(PointerEventData eventData)
{
ObjVector3 = this.transform.position;
if (isDrag&&Input.GetMouseButton(0))
{
StringEventSystem.Global.Send<string>("Begin", eventData.pointerDrag.name);
Debug.Log(eventData.pointerDrag.name);
}
}
public void OnEndDrag(PointerEventData eventData)
{
if (isDrag)
{
this.transform.position = ObjVector3;
StringEventSystem.Global.Send<string>("EndDrag", eventData.pointerDrag.name);
Debug.Log(eventData.pointerDrag.name);
}
}
/// <summary>
/// 物体可拖拽
/// </summary>
/// <param name="eventData"></param>
public void OnDrag(PointerEventData eventData)
{
if (isDrag && Input.GetMouseButton(0))
{
Vector3 screenpos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenpos.z);
this.transform.position = Camera.main.ScreenToWorldPoint(mouseScreenPos);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hits = Physics.RaycastAll(ray);
foreach (var item in hits)
{
if (item.collider != null && item.collider.tag == deskTag)
{
var dis0 = Vector3.Distance(Camera.main.transform.position, item.point);
var offset = collider.bounds.size.magnitude / 2;
var dis1 = Vector3.Distance(Camera.main.transform.position, transform.position) + offset;
if (dis1 > dis0)
{
var precent = 1 - (offset / dis0);
transform.position = Camera.main.transform.position + (item.point - Camera.main.transform.position) * precent;
//transform.position = item.point;
}
//transform.position = item.point;
break;
}
}
}
}
}
然后必须在摄像机上挂载Unity UGUI的PhysicsRaycaster (物理射线检测)
下面介绍一下:
PhysicsRaycaster
【Unity】 UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用-CSDN博客
IDragHandler, IBeginDragHandler, IEndDragHandler
【Unity】IBeginDragHandler、IDragHandler 和 IEndDragHandler 介绍-CSDN博客
问题就是他们都是用于UI 元素的,然后他用在了3D物体上,导致对我的3D物体起作用,如果一定要在相机上挂载PhysicsRaycaster,又要EventSystem.current.IsPointerOverGameObject只对你的UI 元素起作用,那么可以在这个组件上,用EventMask:指定哪些层的UI元素可以接收事件。比如你的模型是层级是
那么你就可以在EventMask上不勾选Model
这样 EventSystem.current.IsPointerOverGameObject()就不会对你指定的模型碰撞体起作用了。。。