最近slg项目中有个需求,场景中有地块,给武将上阵,同时支持拖动,点击等基本操作,同时又要打开UI替换武将,需要处理点击穿透的问题
需求点:
1.点击地块,打开UI,但是不能点穿导致再次打开(其他办法也行不在这讨论);
2.打开UI,阻挡射线点击,和第一点需求差不多
3.Canvas Group只能解决 让射线响应 UI不被响应的需求,而不是UI开启时射线不响应的需求
场景中点击需要打开对应UI,操作一系列上阵创模等功能,但是打开UI的同时,点击到场景中这些碰撞盒,会持续响应,UI上BG image raycasttarget 并不能阻挡射线检测,这时需要代码中做一系列操作.
1.首先UI父物体上添加GraphicRaycaster组件,我这里mask只选了UI,其他不知道,没测试过,
2. 声明各种变量并找到
private GraphicRaycaster RaycastInCanvas;
private EventSystem eventSystem;
3.前任程序的做法是在Update中通过射线检测及完成各种需求
主要做法是Input.GetMouseButtonDown(0) 点击时在判断,增加下列代码
private bool CheckUiRaycastObjects()
{
PointerEventData eventData = new PointerEventData(eventSystem);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;
List
RaycastInCanvas.Raycast(eventData, list);
//Debug.Log(list.Count);
return list.Count > 0;
}
原理大概就是点击的时候判断下是否有UI层并返回响应UI层raycasttarget的组件个数,
这个数量是根据窗口 MaskBG蒙板上 raycasttarget 是否开启来判断
这里顺便说一句,由于项目需求,我们这里非全屏UI一般都有层半透mask(全屏是BG),这个会开启raycasttarget选项,简单粗暴防点穿,其他的除了button 超链接文本 rawimag在模型展示的时候会开启,其余都是关闭状态,否则有一定检测消耗,具体可以看米忽悠大佬整理的,这里不讨论
上面的代码就很简单 如果true 说明有UI层级挡住,ray射线相关操作失效,UI层正常,
false就说明没UI阻挡. 暂时就说到这里
分割线
今天测试报了个bug,还是点穿了,是因为我们ui分了很多层
之前加了GraphicRaycaster 的在main层,但是pop层也有公用窗口,不可能这个公用窗口加上GraphicRaycaster ,所以上面的方法不行,被点穿,参考了这位兄弟的文章,解决了,具体的可以看他的文章解决,大概原理就是先判断手指数量,需要注意pc和真机的区别