[学习笔记]UGUI中UI和3D物体存在的点击响应问题
程序员文章站
2022-03-26 23:19:53
...
常见的有3种情况:
1.点击UI,后面的3D物体不需要响应
2.点击了UI,后面的3D物体同时也需要响应
3.点击了鼠标右键,在点到UI的时候不需要响应
以上几个问题,其实通过 EventSystem.current.IsPointerOverGameObject() 这个方法就能解决掉。
这个方法的含义就是判断当前鼠标是否点击到了UI,并返回布尔值。实现方式大概是这样的:
bool IsPointerOverGameObject()
{
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
graphic.Raycast(eventData, results);
return results.Count > 0;
}
但是这里提出一种新的方式。
我们的3D物体的点击触发事件,一般是用的OnMouseDown 这种自带的方法,
其实也可用点击UI的一套系统,
和UI的点击是一样的:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ThreeDClick : MonoBehaviour, IPointerClickHandler
{
MeshRenderer mesh;
int count = 0;
void Start()
{
mesh = GetComponent<MeshRenderer>();
}
void IPointerClickHandler.OnPointerClick(PointerEventData eventData)
{
if (count.Equals(0))
{
mesh.material.color = Color.yellow;
count = 1;
}
else
{
mesh.material.color = Color.white;
count = 0;
}
}
}
但是UI的事件传递是经过GraphicRaycaster ,这个类只传递继承了Graphic的脚本,对于3D物体是并没有用的。
所以我们需要添加一个叫做PhysicsRaycaster 脚本。
使用同一套事件系统,就不用担心点击了UI之后,会影响后面的3D物体了。
至于第二个问题,可以这么解决:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class UIClick : MonoBehaviour,IPointerClickHandler
{
Image image;
int count = 0;
void Start()
{
image = GetComponent<Image>();
}
public void OnPointerClick(PointerEventData eventData)
{
if (count.Equals(0))
{
image.color = Color.blue;
count = 1;
}
else
{
image.color = Color.red;
count = 0;
}
ExecuteAll(eventData);
}
//再点击了UI之后还能点击3D物体
void ExecuteAll(PointerEventData eventData)
{
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, results);
for (int i = 0; i < results.Count; i++)
{
if (!results[i].gameObject.Equals(this.gameObject))
{
ExecuteEvents.Execute(results[i].gameObject, eventData, ExecuteEvents.pointerClickHandler);
}
}
}
}
就是通过EventSystem得到当前点击到的所有的物体,包括角标为0的UI 和角标为1的3D物体,遍历执行以下后面的事件。
至于第3个问题,使用IsPointerOverGameObject就能很好的解决,其实现的方式,也是判断当前点击到的物体的个数。
上一篇: UGUI实现血条跟随