Unity3d开发UGUI 事件体系分析

2016年10月12日 18:34 0 点赞 0 评论 更新于 2017-05-07 15:29

在众多Unity3D项目中,UGUI得到了广泛应用,但并非所有开发者都深入研究过其内部结构。由于我打算定制自己的UI,因此有必要深入了解UGUI的内部机制。本文将基于UGUI的源码,详细分析其事件体系结构以及点击事件的逻辑流程。

事件体系

UGUI的事件体系主要由四部分构成,分别是监测器、派发器、采集器和响应器。

监测器(EventSystem类)

监测器由EventSystem类实现。该类重写了MonoBehaviorUpdate方法,在每一帧更新挂载于同一个GameObject上的BaseInputModule组件状态。它会判断是否应该激活相应的Module,若激活条件满足,则调用各个ModuleProcess方法。

派发器(BaseInputModule及其子类)

派发器的基类是BaseInputModule,其中最常用的子类是StandaloneInputModule。派发器负责实际的事件生成,具体工作包括确定事件类型、收集事件数据以及过滤派发对象。在获取派发对象时,需要借助采集器的功能,不过这一过程需通过监测器来实现。虽然在实现代码中未体现明显的效率优势,但这种设计从理论上能带来一定的性能提升。

采集器(BaseRaycaster及其子类)

采集器的基类是BaseRaycaster,在UGUI中通常使用其子类GraphicRaycaster。当事件发生时,Module会请求进行射线点触操作,采集器会返回所有能被点到的物体,这些物体随后会被交由派发器进行过滤处理。采集器内部有一个管理类RaycasterManager,它作为链接采集器和监测器的单向桥梁,起到了关键的协调作用。

响应器(IEventSystemHandler及其子类)

响应器是实现事件响应逻辑的核心部分,以IEventSystemHandler及其子类为代表。例如,最常用的IPointerClickHandler用于处理点击事件。通过ExecuteEvents类,可以获取发生事件的对象上所有的响应器,并调用其相应的响应逻辑。以点击事件为例,最终事件会被派发到OnClick的代理上,从而完成逻辑的执行。

这四个模块之间的大致依赖关系如下:监测器负责整体的状态监测和Module的激活管理;派发器依赖监测器获取采集器的信息,完成事件的生成和派发;采集器为派发器提供可派发的对象信息;响应器则负责处理派发过来的事件。

类图

UGUI的类可分为功能类和编辑器类两部分。

功能类

功能类依据前面所述的事件体系,可以清晰地找到重要的基类。下面是与点击事件相关的UML图(此处可根据实际情况插入UML图)。该图仅展示了与点击相关的部分,实际上UGUI还支持许多其他功能,如拖拽、滑动等。一旦掌握了这些重点部分,其他分支逻辑也能较容易地理解。

编辑器类

编辑器类相对简单,我没有单独梳理其类图,直接使用VS自动生成的类图即可满足需求。需要注意的是,若认为这些编辑器类没有用处,那可能是对编辑器代码的理解还不够深入。UGUI的编辑器界面获得了广泛好评,在需要自定义Inspector界面时,其中的一些功能会非常有用。后续有空时,我也打算深入研究这部分内容。

点击的逻辑流程

基于事件体系的划分,下面梳理一次按钮点击的调用逻辑,对应的流程图如下(此处可根据实际情况插入流程图)。

总结

“动手改之前,要先弄明白别人的程序逻辑”,这句话说起来容易,但真正能坚持做好的人并不多。我也是在外层包装了各种控件之后,才下定决心重写UGUI。深入研究UGUI的事件体系花费了不少时间,希望整理出来的这些内容能对大家有所帮助。

作者信息

孟子菇凉

孟子菇凉

共发布了 1189 篇文章