击穿UI, 使下层UI也能触发点击事件
问题:
2个button是叠加摆放的
希望点击时能同时触发2个button
怎么办呢?
方法1.射线穿透全部UI, 返回一个列表, 然后按个找
public class SortPanel : MonoBehaviour
{
EventSystem eventSystem;
GraphicRaycaster RaycastInCanvas;
void Start()
{
RaycastInCanvas = GameObject.Find("Canvas").GetComponent<GraphicRaycaster>();
}
public void MouseEnter(string dragName)
{
PointerEventData eventData = new PointerEventData(eventSystem);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;
//其实上面3行可以不写, 传一个eventData参数进来就好了
List<RaycastResult> list = new List<RaycastResult>();
RaycastInCanvas.Raycast(eventData, list);
if (list.Count > 0)
{
//print(list[i].gameObject.name);
}
}
}
方法2.事件向下传递
↓直接看这篇文章就好了, 写的很好, 亲测可用
https://www.xuanyusong.com/archives/4241
注意一点:
当点到button上挂的text时, 也会触发该button的onClick事件, 这种情况会造成死递归
方法3.实现接口ICanvasRaycastFilter
使用ICanvasRaycastFilter接口, 实现接口的IsRaycastLocationValid, 返回false, 就能使该物体不再遮挡鼠标.
在B站学的, 链接: https://www.bilibili.com/video/BV12g4y1z74J?p=21
using UnityEngine;
using UnityEngine.EventSystems;
public class DragBehavior : MonoBehaviour, ICanvasRaycastFilter
{
bool isDrag;
Vector3 startPos;
Transform father;
void Start()
{
MyEvent.Get(transform).MyBtnDragStart = BeginDrag;
MyEvent.Get(transform).MyBtnDragEnd = EndDrag;
MyEvent.Get(transform).MyBtnDrag = Drag;
father = transform.parent;
}
private void BeginDrag(GameObject arg1, PointerEventData arg2)
{
startPos= transform.position;
transform.parent = C3ModelControl.GetInstance().canvas.transform;
isDrag = true;
}
//因为被击穿, 检测不到鼠标了, 所以拖拽逻辑写在了Update里
private void Drag(GameObject arg1, PointerEventData arg2)
{
// transform.position = arg2.position;
}
private void EndDrag(GameObject arg1, PointerEventData arg2)
{
//isDrag = false;
//transform.position = startPos;
//transform.parent = father;
}
//不能直接return false; 因为如果那样的话, 连BeginDrag也无法响应
//返回!isDrag, 该物体就仅能响应BeginDrag了
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
return !isDrag;
}
private void Update()
{
if (isDrag)
{
transform.position = Input.mousePosition;
}
if (Input.GetMouseButtonUp(0) && isDrag)
{
isDrag = false;
transform.position = startPos;
transform.parent = father;
}
}
}
我真傻, 真的, 我单知道Up主在UI穿透后, Drag就不能用了, 我不知道自己的竟然仍然能用.
如下, 不把方法写进Update里, 也能实现拖拽, 因为我用的是EventTrigger.
using UnityEngine;
using UnityEngine.EventSystems;
public class DragBehavior : MonoBehaviour, ICanvasRaycastFilter
{
bool isDrag;
Vector3 startPos;
Transform father;
void Start()
{
MyEvent.Get(transform).MyBtnDragStart = BeginDrag;
MyEvent.Get(transform).MyBtnDragEnd = EndDrag;
MyEvent.Get(transform).MyBtnDrag = Drag;
father = transform.parent;
}
private void BeginDrag(GameObject arg1, PointerEventData arg2)
{
startPos= transform.position;
transform.parent = C3ModelControl.GetInstance().canvas.transform;
isDrag = true;
}
private void Drag(GameObject arg1, PointerEventData arg2)
{
transform.position = arg2.position;
}
private void EndDrag(GameObject arg1, PointerEventData arg2)
{
isDrag = false;
C3SceneData.currentDrag = "";
SortPanel.instance.MouseEnter(this.name);
transform.position = startPos;
transform.parent = father;
}
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
return !isDrag;
}
//private void Update()
//{
// if (isDrag)
// {
// transform.position = Input.mousePosition;
// }
// if (Input.GetMouseButtonUp(0) && isDrag)
// {
// isDrag = false;
// C3SceneData.currentDrag = "";
// SortPanel.instance.MouseEnter(this.name);
// transform.position = startPos;
// transform.parent = father;
// }
//}
}