UGUI EventSystem源码剖析,看这一篇就全明白了
系列
文章目录
EventSystem
Related Class: BaseInputModule、BaseEventData、 ExecuteEvents、RaycasterManager+
Related Interface: 无
Related Other: 无
Intro: UGUI事件管理系统,通过此系统完成我们所知的UI交互。
基本使用:GameObject上挂有IEventSystemHandler组件并是可用状态
EventSystem:
管理 所有的输入检测模块(InputModule)并帧调用Module的执行(Process)
调动射线捕捉模块(Raycasters),为InputModule提供结果(具体的触点所穿透的对象信息)
InputModule 管理更新EventData 判断当前的操作事件,并通知具体的EventSystemHandler 进行逻辑处理
EventData
主要分三类来存储事件信息,对应具体的EventSystemHandler
- BaseEventData:基础的事件信息
- PointerEventData: 存储 触摸/点击/鼠标操作 事件信息
- AxisEventData:移动相关的事件信息,注:拖动的操作属于PointerEventData
BaseInputModule
被EventSystem帧调用,检查Input中各项数值 => 判断当前操作状态,更新/创建 PointerEventData并以当前操作状态进行组装 => Mouse : buttonData Touch : m_PointerData
主要分为单点触控(StandaloneInputModule)与多点触控(TouchInputModule Touch模块已经整合进Standalone中)模块。
- ProcessMouseEvent:处理所有鼠标事件
- ProcessTouchEvents:处理所有触点事件
ProcessMouseEvent
- MouseState :获取当前鼠标状态即鼠标左键、右键、中键的状态(ButtonState)
- ProcessMousePress、ProcessMove、ProcessDrag 检测各个ButtonState下的PointerEventData
- 满足条件则执行相应的事件(ExecuteEvents)
ProcessTouchEvents
- ProcessTouchPress、ProcessMove、ProcessDrag 检测TouchId下的PointerEventData
- 满足条件则执行相应的事件(ExecuteEvents)
Raycasters
在事件系统中充当捕获物体的角色,管理射线,为InputModule提供gameObject
RaycasterManager
管理了一个 RaycasterList,通过EventSystem.RaycastAll提供给InputModule
- Raycaster启用时(Enable)加入List
- Raycaster弃用时(Disable)移除List
Physics2DRaycaster PhysicsRaycaster
由Manager触发射线(Raycast),返回射线结果(RaycastResult)
2D与3D分别使用了Physics2D/Physics 中射线穿透获取交点信息的方法
Raycast的过程
-
module.Raycast(eventData, raycastResults); EventSystem启动射线
-
ray = eventCamera.ScreenPointToRay(eventData.position); 通过位置信息获取射线
-
m_Hits = ReflectionMethodsCache.Singleton.raycast3DAll(ray, ...);通过射线获取穿透数据
-
var result = new RaycastResult{....};resultAppendList.Add(result);将穿透数据进行封装
RaycastResult
射线数据封装结构,包含了有关射线经过物体的具体信息
EventSystemHandler
事件处理者,这里会提供许多事件接口。最终事件响应的具体逻辑就由我们继承这些接口来书写。
主要分为三种类型
- IPointerXXXHandler : 处理鼠标点击和触屏事件
- IDragXXXXHandler:处理拖拽事件
- IXXXHandler:处理其他如选择、取消等事件
ExecuteEvents
事件执行器,提供了一些通用的处理方法。
Execute过程:
GetEventList<T>(target, internalHandlers); 获取物体上所有包含IEventSystemHandler且可用的组件
arg = (T)internalHandlers[i]; 找到具体T类型组件
functor(arg, eventData); 执行
handler.OnXXXX(ValidateEventData<XXXXEventData>(eventData)); functor 类似这样
ExecuteHierarchy:逐节点寻找可执行的物体(含可用的IEventSystemHandler),触发(Execute)即停止逐根搜索,return