今天研究下UGUI的源码,先从EventSystem入手。EventSystem是用来处理点击、键盘输入以及触摸等事件的。

1.BaseInputModule

EventSystem开头声明了两个变量,系统的输入模块列表和当前输入模块

     private List<BaseInputModule> m_SystemInputModules = new List<BaseInputModule>();

        private BaseInputModule m_CurrentInputModule;

BaseInputModule是一个抽象类,PointerInputModule继承于BaseInputModule,也是一个抽象类,StandaloneInputModule和TouchInputModule又继承于PointerInputModule。

StandaloneInputModule:基本的键盘和鼠标输入系统,并跟踪鼠标的位置,以及鼠标/键盘所按下的按键,是面向pc平台的输入模块。

TouchInputModule:基本的触摸输入系统,用于处理触摸、拖拽以及位置数据,是面向移动平台的输入模块。

EventSystem的Update函数中会执行TickModules函数,用于更新m_SystemInputModules的每一个输入模块。

然后遍历m_SystemInputModules,判断是否支持当前平台且处于激活状态,若有赋值给m_CurrentInputModule,若无便选择m_SystemInputModules的第一个支持当前平台的输入模块赋值给m_CurrentInputModule。

再判断是否满足条件if (!changedModule && m_CurrentInputModule != null),当前输入模块执行Process函数,m_CurrentInputModule.Process();

StandaloneInputModule的Process函数中,会把各类事件传递给EventSystem的m_CurrentSelected。m_CurrentSelected由SetSelectedGameObject方法进行设置,并且会对上一个被选中的对象执行取消事件,对新设置的对象执行选中事件。

ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.deselectHandler);
m_CurrentSelected = selected;
ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.selectHandler);

TouchInputModule的Process函数中,会根据是否支持触摸,分别执行FakeTouches(用鼠标模拟触摸)和ProcessTouchEvents函数。ProcessTouchEvents会调用GetTouchPointerEventData函数,GetTouchPointerEventData会通过eventSystem.RaycastAll函数找到第一个被射线照射到的对象,存到一个PointerEventData变量中。然后根据这个PointerEventData变量执行相应的触摸、拖拽等事件。

private void ProcessTouchEvents()
{
for (int i = ; i < input.touchCount; ++i)
{
Touch touch = input.GetTouch(i); if (touch.type == TouchType.Indirect)
continue; bool released;
bool pressed;
var pointer = GetTouchPointerEventData(touch, out pressed, out released); ProcessTouchPress(pointer, pressed, released); if (!released)
{
ProcessMove(pointer);
ProcessDrag(pointer);
}
else
RemovePointerData(pointer);
}
}

2.事件接口

上文提到过ExecuteEvents.Execute函数执行事件,ExecuteEvents是一个静态类,里面声明了一个泛型委托EventFunction,对EventInterfaces的大部分接口声明EventFunction类型的委托变量和函数。例如:

        private static readonly EventFunction<ISelectHandler> s_SelectHandler = Execute;

        private static void Execute(ISelectHandler handler, BaseEventData eventData)
{
handler.OnSelect(eventData);
}

在EventSystem里调用:

ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.selectHandler);

在ExecuteEvents的Execute函数中

public static bool Execute<T>(GameObject target, BaseEventData eventData, EventFunction<T> functor) where T : IEventSystemHandler

会执行functor(arg, eventData),也就是执行arg.OnSelect(eventData)。

EventInterfaces的接口如下:

IPointerEnterHandler//指针进入

IPointerExitHandler//指针离开

IPointerDownHandler//指针按下

IPointerUpHandler//指针抬起

IPointerClickHandler//指针点击

IBeginDragHandler//开始拖拽

IInitializePotentialDragHandler//当发现拖动但在开始拖动有效之前由BaseInputModule调用

IDragHandler//拖拽中

IEndDragHandler//结束拖拽

IDropHandler//结束拖拽时所在gameobject调用

IScrollHandler//鼠标滚轮

IUpdateSelectedHandler//选中物体时,持续触发

ISelectHandler//选中物体

IDeselectHandler//取消选中物体

IMoveHandler//物体移动

ISubmitHandler//提交按钮被按下

ICancelHandler//取消按钮被按下

UGUI源码之EventSystem的更多相关文章

  1. 【UGUI源码分析】Unity遮罩之Mask详细解读

    遮罩,顾名思义是一种可以掩盖其它元素的控件.常用于修改其它元素的外观,或限制元素的形状.比如ScrollView或者圆头像效果都有用到遮罩功能.本系列文章希望通过阅读UGUI源码的方式,来探究遮罩的实 ...

  2. 【UGUI源码分析】Unity遮罩之RectMask2D详细解读

    遮罩,顾名思义是一种可以掩盖其它元素的控件.常用于修改其它元素的外观,或限制元素的形状.比如ScrollView或者圆头像效果都有用到遮罩功能.本系列文章希望通过阅读UGUI源码的方式,来探究遮罩的实 ...

  3. UGUI源码之Selectable

    Selectable是Button.InputField.Toggle.ScrollBar.Slider.Dropdown的基类. Selectable的继承的类与接口如下: public class ...

  4. uGUI源码调试

    uGUI源代码地址:https://bitbucket.org/Unity-Technologies/ui 工具编译后转换位置{Unity3D_Vserion}\Editor\Data\UnityEx ...

  5. UGUI源码之Graphic

    Graphic是用来显示图像的一个抽象类,是MaskableGraphic的父类,而MaskableGraphic是Image.RawImage.Text的父类. Graphic继承于UIBehavi ...

  6. Unity UGUI图文混排源码(一)

    Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...

  7. [UGUI]图文混排(二):Text源码分析

    UGUI源码: https://bitbucket.org/Unity-Technologies/ui/downloads/?tab=tags 首先下载一份UGUI源码,这里我下载的版本是5.3.2f ...

  8. Unity UGUI图文混排源码(三) -- 动态表情

    这里是根据图文混排源码(二)进一步修改的,其他链接也不贴了,就贴一个链接就好了,第一次看这文章的同学可以先去看看其他几篇文章 Unity UGUI图文混排源码(二):http://blog.csdn. ...

  9. Unity UGUI图文混排源码(二)

    Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...

随机推荐

  1. Nginx 的 location

    一.location语法 语法: Syntax: location [ = | ~ | ~* | ^~ ] uri { ... } location @name { ... } Default: — ...

  2. <STL源码剖析> 6.3.6 power

    计算power的算法说明 http://www.sxt.cn/u/324/blog/2112 翻译自  http://videlalvaro.github.io/2014/03/the-power-a ...

  3. 2019-1-4-win10-uwp-win2d-CanvasVirtualControl-与-CanvasAnimatedControl

    title author date CreateTime categories win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl ...

  4. H3C 单区域OSPF配置示例一(续)

  5. 如何理解springMVC?

    springMVC 工作原理? 简单理解:客户端发送请求-->前端控制器接受客户端的请求DispathServelt-->找到处理器映射HandMapping-->找到处理器hand ...

  6. 大众点评实时监控系统CAT的那些坑

    首先,感谢大众点评开源监控系统CAT.CAT是一款非常使用的功能建全的监控系统.作为一个知名的开源软件,真的是太差了. 想把CAT用起来,没有多年的Java经验是不行的.先吐槽一下,再写一篇如何用的文 ...

  7. 连接远程mysql(Linux环境)

    保证三点: 1.打开/etc/my.cnf,找到[mysqld]项,在其后加入一句:skip-name-resolve,保存,重启mysql服务. service mysqld restart  或者 ...

  8. C# AutoResetEvent 理解

    .. AutoResetEvent在内存中保持着一个bool值值为False,则使线程阻塞:值为True,使线程退出阻塞: 创建AutoResetEvent对象的实例,在函数构造中传递默认的bool值 ...

  9. 关于redis有序集合http://www.runoob.com/redis/redis-sorted-sets.html

    redis有序集合和集合一样,元素都是字符串类型,而且不能重复 和普通集合不同的是它关联一个double类型的分数,redis是同个元素的分数来对元素进行排序 有序集合的元素是唯一的,但是分数可以重复 ...

  10. scrf 原理及flask-wtf防护

    了解什么是scrf? SCRF跨站点请求伪造Cross—Site Request Forgery) 指恶意用户通过个人用户的点击,然而盗用用户的账号信息,并发送邮件.虚拟货币的转账,以及一些重要的事务 ...