前言
我本来是使用Input类输入来直接写UI逻辑的
但是在我添加弹窗并用弹窗做一些操作的时候,发生了“穿透”现象
也就是在对弹窗做操作的时候,下层UI也对操作做出了反应
这个的罪魁祸首就是Input类,它在任何时候都会做出反应,并不能结合到Event的事件拦截
因此感悟:果然UI还是得用EventSystem+EventTrigger啊
为什么不用Input类
因为Input一定会被用于游戏内UI外的输入处理,它与EventSystem(UI的事件接收系统)是隔离的。
如果使用UI的时候使用Input来自行写方法的调用,那么就会出现在不需要调用某UI的方法的时候调用了的现象。
所以UI层还是少用Input(的鼠标)比较好
EventTrigger的坑
仅说我碰到的。
类似以下描述的坑应该均可以用本文的方法解决。
组件描述
- EventTrigger这个组件,熟悉Unity的人应该都知道,是为UI(UGUI)提供的事件触发组件。
- UI的操作基本都是和鼠标(或者触摸)相关的。
- 它已经封装好了许多的事件,我们使用的时候只需要添加相应的方法到对应的事件回调列表中即可,包括鼠标的按下/抬起/点击、鼠标拖拽的开始/进行/结束等。
它的坑
描述
鼠标的按下与抬起、拖拽的开始与结束是捆绑的!(我只用到了这两组,其他的同类关联性事件应该也类似)
具体表现
当为一个物体设置了鼠标的按下和抬起两个事件时(假设这个物体叫item),鼠标对其按下,然后移动到其他同样挂载有此事件的UI上(比如叫item001),然后再松开,它会调用的不是item001的抬起事件,而是item的抬起事件!
所以当你需要触发item001的抬起事件时会变得没法触发。
解决方案
本来试图直接从EventSystem接管UI事件的,但是好像还是得实现对应的handler(事件接口)才行,因此把目光放在了如何让trigger触发真实的射线检测到的UI的事件
我想到的方案是事件转发,也就是在触发事件后,调用真正需要调用的事件。
具体代码
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
namespace Assets.Scripts.Utils
{
/// <summary>
/// 重写的事件触发器
/// </summary>
public class UIEventListener : EventTrigger
{
public override void OnPointerDown(PointerEventData eventData)
{
// 检测并转发事件到正确的物体上
var triggerObject