ugui源码理解 - 事件系统

主要涉及到的类

看到最多的就是EventSystem这个自动添加的GameObject

 

代码阅读要点

1) 事件系统做了什么?

在Update中不断的检测这一帧发生的输入事件,并根据输入事件解析出当前在进行的操作。

所以,所有的逻辑都是在EventSystem.Update中发生的。StandaloneInputModule主要负责把输入事件解析为操作(StandaloneInputModule.Process函数中)。

 

2) 输入事件和操作

a) 在PC上,输入事件主要包括:光标移动,鼠标按键按下,鼠标按键抬起,鼠标滚轮滚动

b) 在手机上,输入事件主要包括:手指按下,手指按在屏幕上移动,手指抬起

Unity对两者进行了统一抽象,光标和手指统一叫Pointer,按下后移动统一叫拖拽等,他定义了以下的这些操作回调接口。

 

3) 相关操作的解析流程

 

a) 在按钮上点击:光标移动进入按钮范围(OnPointerEnter) -> 按下鼠标左键(OnPointerDown) -> 没有发生移动 -> 在一开始按下的按钮上抬起鼠标左键(OnPointerUp, OnPointerClick)

OnPointerEnter的触发流程:EventSystem.Update -> StandaloneInputModule.Process -> StandaloneInputModule.ProcessMouseEvent -> PointernputModule.ProcessMove -> PointernputModule.HandlePointerExitAndEnter

OnPointerDown的触发流程:EventSystem.Update -> StandaloneInputModule.Process -> StandaloneInputModule.ProcessMouseEvent -> StandaloneInputModule.ProcessMousePress

OnPointerUp的触发流程:EventSystem.Update -> StandaloneInputModule.Process -> StandaloneInputModule.ProcessMouseEvent -> StandaloneInputModule.ProcessMousePress,同样是这个函数,进入另一个分支

OnPointerClick的触发流程:和OnPointerUp一个分支,只是抬起时的对象要和按下时是同一个才行,比如:按下时是在Btn1,抬起时却是在Btn2上(中间移动了),那就不会被认为是点击。

 

b) 拖拽移出拖拽区域:光标移动进入按钮范围(OnPointerEnter) -> 按下鼠标左键(OnPointerDown) -> 左键继续按着, 移动光标(OnBeginDrag, OnPointerUp, OnDrag) -> 光标移出按钮范围(OnPointerExit) -> 抬起鼠标左键(OnPointerUp)

OnBeginDrag的触发:EventSystem.Update -> StandaloneInputModule.Process -> StandaloneInputModule.ProcessMouseEvent -> PointernputModule.ProcessDrag

移动光标时为啥还会触发一个OnPointerUp?比如:点在Scroll View中的一个按钮上,然后拖动,这个按钮就会收到OnPointerUp回调了。

OnDrag的触发:和OnBeginDrag一个分支,OnBeginDrag先触发且只触发一次,OnDrag后触发且只要有移动输入事件就会一直触发。

OnPointerExit的触发:EventSystem.Update -> StandaloneInputModule.Process -> StandaloneInputModule.ProcessMouseEvent -> PointernputModule.ProcessMove -> PointernputModule.HandlePointerExitAndEnter

 

c) 拖拽移出拖拽区域再移回来:光标移动进入按钮范围(OnPointerEnter) -> 按下鼠标左键(OnPointerDown) -> 左键继续按着, 移动光标(OnBeginDrag, OnPointerUp, OnDrag) -> 光标移出按钮范围(OnPointerExit) -> 光标再移入按钮范围(OnDrag, OnPointerEnter) -> 抬起鼠标左键(OnPointerUp, OnPointerClick, OnEndDrag)

OnEndDrag的触发:和OnPointerUp一个分支,只是多了if (pointerEvent.pointerDrag != null && pointerEvent.dragging)判断

 

d) 光标移动进入按钮范围(OnPointerEnter) -> 滚轮滚动(OnScroll) -> 光标移出按钮范围(OnPointerExit) -> 滚轮滚动(无)

OnScroll的触发:EventSystem.Update -> StandaloneInputModule.Process -> StandaloneInputModule.ProcessMouseEvent

 

4) PointerEventData类

这个类的作用也很重要,相当于一个状态记录对象,会记录Pointer按下到抬起期间的的状态,根据状态来判断出当前的操作。

上面的相关变量记录的状态的用途

pointerId:一般第1个放下的手指为0,第2个为1,第3个为2,以此类推;如果中途第2个手指抬起了,那屏幕上还有pointerId为0, 2的手指

position:Pointer的当前位置

delta:Pointer与上次位置的变化

pointerEnter:用于记录实现了IPointerEnterHandler接口的对象

rawPointerPress:用于记录Pointer在哪个对象上按下的

pointerPress:用于记录实现了IPointerDownHandler或IPointerClickHandler接口的对象,是rawPointerPress或其祖先对象

lastPress, clickTime, clickCount:用于跟踪双击

eligibleForClick:可以在Click触发前,设为false,就不触发了

pointerDrag:用于记录实现了IPointerDragHandler接口的对象,是rawPointerPress或其祖先对象

dragging:用于记录是否是dragBegin

 

posted @ 2023-07-13 00:27  yanghui01  阅读(105)  评论(0编辑  收藏  举报