UGUI源码相关学习(一)事件检测相关

UGUI是建立在3D网格下的。也就是说UI在被实例化时,第一件事就是构建网格


事件数据模块:

AxisEventData 记录滚轮数据信息
PointerEventData 记录鼠标触摸位置,点击位置,上次点击的时间,点击次数等数据


输入事件捕获模块:

BaseInputModule 基类模块,PointerInputModule继承自BaseInputModule。这个模块类内置了几个状态类如MouseState、MouseButtonEventData、ButtonState。给输入添加了类型和状态。
StandaloneInputModule、TouchInputModule 均继承自PointerInputModule
StandaloneInputModule和TouchInputModule才是真正处理事件的模块

ProcessMouseEvent函数处理鼠标所有的事件包括鼠标按下、移动、滚轮、拖拽。函数内部逻辑主要调用了ProcessMousePress、ProcessMove、ProcessDrag函数。

ProcessMousePress函数:
开始定义了一个名字为pointerEvent的参数用于存储调用鼠标事件句柄(如IPointerClickHandler鼠标按下)前后的数据。这里处理了鼠标按下、拖拽、鼠标抬起、点击、拖拽结束、等事件句柄。
ProcessDrag函数:
主要进行判断、根据拖拽情况执行开始拖拽句柄和拖拽中句柄等
ProcessMove函数:没有判断直接执行相应句柄

TouchInputModule模块中核心函数是ProcessTouchEvents这个函数是这样的, 具体执行和StandaloneInputModule差不多

// 所有触碰到的点都会执行
// 
private void ProcessTouchEvents()
{
    for (int i = 0; i < Input.touchCount; ++i)
    {
        Touch input = Input.GetTouch(i);

        bool released;
        bool pressed;
        var pointer = GetTouchPointerEventData(input, out pressed, out released);

        ProcessTouchPress(pointer, pressed, released);

        if (!released)
        {
            ProcessMove(pointer);
            ProcessDrag(pointer);
        }
        else
            RemovePointerData(pointer);
    }
}

这2个模块中调用大量ExecuteEvents.ExecuteHierarchy,ExecuteEvents.Execute。下面学习这2个函数组成。

private static readonly List<Transform> s_InternalTransformList = new List<Transform>(30);

public static GameObject ExecuteHierarchy<T>(GameObject root, BaseEventData eventData, EventFunction<T> callbackFunction) where T : IEventSystemHandler
{
    // 获取物体的所有父节点,包括它自己
    GetEventChain(root, s_InternalTransformList);

    for (var i = 0; i < s_InternalTransformList.Count; i++)
    {
        var transform = s_InternalTransformList[i];
        // 对每个父节点包括自己依次执行句柄响应
        if (Execute(transform.gameObject, eventData, callbackFunction))
            return transform.gameObject;
    }
    return null;
}

这里作者说的是 当前节点事件会通知到父节点。(TODO为什么要通知父节点)


射线检测模块

在GraphicRaycaster类中函数 private static void Raycast(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, IList<Graphic> foundGraphics, List<Graphic> results)。其中明确了if (graphic.depth == -1 || !graphic.raycastTarget || graphic.canvasRenderer.cull)深度为-1或者没有勾选raycastTarget 将会跳过。


事件处理逻辑

EventSystem是主要的逻辑入口、EventInterfaces,EventTrigger,EventTriggerType定义了一系列回调函数
其中主要通过判断事件是否成立然后调用ExecuteEvents.Execute,并将事件数据传入

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值