Unity3d开发UGUI 事件体系分析
在众多Unity3D项目中,UGUI得到了广泛应用,但并非所有开发者都深入研究过其内部结构。由于我打算定制自己的UI,因此有必要深入了解UGUI的内部机制。本文将基于UGUI的源码,详细分析其事件体系结构以及点击事件的逻辑流程。
事件体系
UGUI的事件体系主要由四部分构成,分别是监测器、派发器、采集器和响应器。
监测器(EventSystem类)
监测器由EventSystem
类实现。该类重写了MonoBehavior
的Update
方法,在每一帧更新挂载于同一个GameObject
上的BaseInputModule
组件状态。它会判断是否应该激活相应的Module
,若激活条件满足,则调用各个Module
的Process
方法。
派发器(BaseInputModule及其子类)
派发器的基类是BaseInputModule
,其中最常用的子类是StandaloneInputModule
。派发器负责实际的事件生成,具体工作包括确定事件类型、收集事件数据以及过滤派发对象。在获取派发对象时,需要借助采集器的功能,不过这一过程需通过监测器来实现。虽然在实现代码中未体现明显的效率优势,但这种设计从理论上能带来一定的性能提升。
采集器(BaseRaycaster及其子类)
采集器的基类是BaseRaycaster
,在UGUI中通常使用其子类GraphicRaycaster
。当事件发生时,Module
会请求进行射线点触操作,采集器会返回所有能被点到的物体,这些物体随后会被交由派发器进行过滤处理。采集器内部有一个管理类RaycasterManager
,它作为链接采集器和监测器的单向桥梁,起到了关键的协调作用。
响应器(IEventSystemHandler及其子类)
响应器是实现事件响应逻辑的核心部分,以IEventSystemHandler
及其子类为代表。例如,最常用的IPointerClickHandler
用于处理点击事件。通过ExecuteEvents
类,可以获取发生事件的对象上所有的响应器,并调用其相应的响应逻辑。以点击事件为例,最终事件会被派发到OnClick
的代理上,从而完成逻辑的执行。
这四个模块之间的大致依赖关系如下:监测器负责整体的状态监测和Module
的激活管理;派发器依赖监测器获取采集器的信息,完成事件的生成和派发;采集器为派发器提供可派发的对象信息;响应器则负责处理派发过来的事件。
类图
UGUI的类可分为功能类和编辑器类两部分。
功能类
功能类依据前面所述的事件体系,可以清晰地找到重要的基类。下面是与点击事件相关的UML图(此处可根据实际情况插入UML图)。该图仅展示了与点击相关的部分,实际上UGUI还支持许多其他功能,如拖拽、滑动等。一旦掌握了这些重点部分,其他分支逻辑也能较容易地理解。
编辑器类
编辑器类相对简单,我没有单独梳理其类图,直接使用VS自动生成的类图即可满足需求。需要注意的是,若认为这些编辑器类没有用处,那可能是对编辑器代码的理解还不够深入。UGUI的编辑器界面获得了广泛好评,在需要自定义Inspector
界面时,其中的一些功能会非常有用。后续有空时,我也打算深入研究这部分内容。
点击的逻辑流程
基于事件体系的划分,下面梳理一次按钮点击的调用逻辑,对应的流程图如下(此处可根据实际情况插入流程图)。
总结
“动手改之前,要先弄明白别人的程序逻辑”,这句话说起来容易,但真正能坚持做好的人并不多。我也是在外层包装了各种控件之后,才下定决心重写UGUI。深入研究UGUI的事件体系花费了不少时间,希望整理出来的这些内容能对大家有所帮助。