EventSystem current
当一个EventSystem组件OnEnable的时候会将这个对象加入到m_EventSystems。
m_EventSystems.Add(this);
OnDisable的时候会将current从m_EventSystems移除
m_EventSystems.Remove(this);
输入模块的抽象类:BaseInputMoudle继承自UIBehaviour
继承关系:
BaseInputModule抽象类
PointerInputModule抽象类
StandaloneInputModule类,面向“PC, Mac& Linux Standalone”这个平台的输入模块
TouchInputModule类,面向“IOS Android”等可触摸移动平台的输入模块(2017.4之后被弃用,集成到StandaloneInputModule)
Update()方法
1.EventSystem会在Update里面每一帧去调用TickModules方法,刷新每一个InputMoudle.
2.在TickMoudle方法里面遍历m_SystemInputModules(也就是所有的输入模块),调用各自输入模块的UpdateMoudle方法,并且判断这些InputMoudle是否支持当前平台IsModuleSupported,并且是否可以激活ShouldActivateModule
3.如果当前输入模块m_CurrentInputModule为Null,把符合条件的module赋值给m_CurrentInputModule并且break,调用ActivateModule激活InputModule,接着eventSystem.SetSelectedGameObject方法设置m_CurrentSelected.
4.如果InputModule没有发生变化,并且m_CurrentInputModule不为Null,调用
Process方法,发送事件SendUpdateEventToSelectedObject给当前选中的物体(m_CurrentSelected),先调用ProcessTouchEvents处理触摸事件,如果没有触摸并且Input的mousePresent为true,ProcessMouseEvent执行鼠标处理事件
5.m_CurrentSelected大部分情况是Selectable组件(继承它的Button、Dropdown、InputField等组件)设置的。设置m_CurrentSelected,实际调用eventSystem.SetSelectedGameObject,会通过ExecuteEvents这个类对之前的对象执行一个被取消事件,且对新选中的对象执行一个被选中事件。这就是OnSelect和OnDeselect两个方法的由来。
EventSystem的RaycastAll方法
在PointerInputModule类中处理触摸事件ProcessTouchEvents和鼠标事件ProcessMouseEvent中分别调用GetTouchPointerEventData,GetMousePointerEventData,RaycastAll方法就是在此时被调用。在RaycastAll方法里面会拿到RaycasterManager里面持有的BaseRaycaster列表并且循环投射射线,然后拿到所有投射结果RaycastResult.结果会根据相机的depth,RaycastResult的sortOrderPriority,renderOrderPriority,sortingLayer,sortingOrder,depth以及distance进行比较排序.
ProcessTouchEvents()
1.遍历所有的输入InputTouch
2.调用RaycastAll方法并且拿到第一个被照射到的RaycastResult
3.执行ProcessTouchPress并且触发触摸事件,传入相应的事件接口类型,由ExecuteEvents.Execute()调用目标对象上的事件接口方法,执行事件,比如在按下的时候执行
松开的时候执行
4.如果触摸没有松开就会执行ProcessMove和ProcessDrag,否则就调用RemovePointerData移除掉PointData
ProcessMouseEvent()
1.获取鼠标的input输入
2.调用RaycastAll方法并且拿到第一个被照射到的RaycastResult
3.依次左键,右键,中键的点击事件
4.在处理按键的点击事件中ExecuteEvents.Execute()调用目标对象上的事件接口方法,执行事件。
IsPointerOverGameObject
是EventSystem类里特别常用的一个方法,用于判断是否点击在UI上,具体是在PointerInputModule中实现的,判断最后一次点击的EventData数据是否为空,不为空即在UI上。