UGUI的源码还是非常清晰的,打开源码可以发现,
从UGUI的源码可知:在EventSystem中调用每一帧函数来实现:

  1. private void TickModules()
  2. {
  3. for (var i = 0; i < m_SystemInputModules.Count; i++)
  4. {
  5. if (m_SystemInputModules[i] != null)
  6. m_SystemInputModules[i].UpdateModule();
  7. }
  8. }

这段代码可以得到当前输入InputModule的position,接着在GetMousePointerEventData函数中存在这一段代码:

  1. public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults)
  2. {
  3. raycastResults.Clear();
  4. var modules = RaycasterManager.GetRaycasters();
  5. for (int i = 0; i < modules.Count; ++i)
  6. {
  7. var module = modules[i];
  8. if (module == null || !module.IsActive())
  9. continue;
  10.         module.Raycast(eventData, raycastResults);
  11.     }
  12.     raycastResults.Sort(s_RaycastComparer);
  13. }

你会发现s_RaycastComparer这样一个函数,该函数就是对所有射线射到的物体进行排序,哈哈,终于找到这个函数了,看看它的实现:

  1. private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
  2. {
  3. if (lhs.module != rhs.module)
  4. {
  5. if (lhs.module.eventCamera != null && rhs.module.eventCamera != null && lhs.module.eventCamera.depth != rhs.module.eventCamera.depth)
  6. {
  7. // need to reverse the standard compareTo
  8. if (lhs.module.eventCamera.depth < rhs.module.eventCamera.depth)
  9. return 1;
  10. if (lhs.module.eventCamera.depth == rhs.module.eventCamera.depth)
  11. return 0;
  12.             return -1;
  13.         }
  14.         if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority)
  15.             return rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority);
  16.         if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority)
  17.             return rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority);
  18.     }
  19.     if (lhs.sortingLayer != rhs.sortingLayer)
  20.     {
  21.         // Uses the layer value to properly compare the relative order of the layers.
  22.         var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer);
  23.         var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer);
  24.         return rid.CompareTo(lid);
  25.     }
  26.     if (lhs.sortingOrder != rhs.sortingOrder)
  27.         return rhs.sortingOrder.CompareTo(lhs.sortingOrder);
  28.     if (lhs.depth != rhs.depth)
  29.         return rhs.depth.CompareTo(lhs.depth);
  30.     if (lhs.distance != rhs.distance)
  31.         return lhs.distance.CompareTo(rhs.distance);
  32.     return lhs.index.CompareTo(rhs.index);
  33. }

来分析下这段代码的实现:

  • 如果Canvas指定了摄像机,就按照摄像机的depth排序。

  • 按照sortOrderPriority的顺序排序。

  • 按照renderOrderPriority排

  • 按depth排(针对GraphicRaycaster),其他两种物理射线(PhysicsRaycaster,Physics2DRaycaster)的depth为0。

  • 按distance排、这里是针对两种物理射线的方式,为射线到物体的距离。

  • 按index排,无论是哪种射线模式,都会将射线碰撞到的UI物体压入到列表中,这里的index就是列表的索引值。

如何找到已经实现了该事件的组件?

在ExecuteEvents的类中有这样一段代码:

  1. private static void GetEventChain(GameObject root, IList<Transform> eventChain)
  2. {
  3. eventChain.Clear();
  4. if (root == null)
  5. return;
  6.     var t = root.transform;
  7.     while (t != null)
  8.     {
  9.         eventChain.Add(t);
  10.         t = t.parent;
  11.     }
  12. }

这段代码一直在点击的gameobject上递归寻找它的父类,然后加入到列表当中。只要有一个父类实现了该接口就会触发该接口事件。然后返回该gameObject。

做实验的话,可以在父对象上实现一个接口函数,点击子对象发现父对象的函数触发了。自己亲测可行。

UGUI的事件系统分析的更多相关文章

  1. UGUI穿透3D世界判断&&UGUI全事件监听

    public bool isPointUI(){ PointerEventData eventDataCurrnt = new PointerEventData (EventSystem.curren ...

  2. UGUI动态绑定事件

    using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;using UnityEngine. ...

  3. UGUI双击事件

    经测试在Android.ios平台下无效 using UnityEngine; using UnityEngine.EventSystems; using System.Collections; us ...

  4. UGUI研究院之控件以及按钮的监听事件系统

    继续学习,我相信大家在做NGUI开发的时候处理事件都会用到UIEventListener,那么UGUI中怎么办呢?先看UGUI的事件有那些吧 Supported Events The Eventsys ...

  5. uGUI VS NGUI

    前言 这篇日志的比较是根据自己掌握知识所写的,请各路大神多多指教. 引擎版本: Unity 4.6 beta 两者区别 1.uGUI的Canvas 有世界坐标和屏幕坐标 2.uGUI的Button属性 ...

  6. 用uGUI开发自定义Toggle Slider控件

    一.前言 写完<Unity4.6新UI系统初探>后,我模仿手机上的UI分别用uGui和NGUI做了一个仅用作演示的ToggleSlider,我认为这个小小的控件已能体现自定义控件的开发过程 ...

  7. 转:UGUI与NGUI的区别与优缺点

    1. NGUI与UGUI的区别 1) uGUI的Canvas 有世界坐标和屏幕坐标   2) uGUI的Image可以使用material     3) UGUI通过Mask来裁剪,而NGUI通过Pa ...

  8. Unity3D研究院之将UI的点击事件渗透下去(转)

    转自 http://www.xuanyusong.com/archives/4241 处理UI还有3D模型的点击推荐使用UGUI的这套事件系统,因为使用起来比较简洁,不需要自己用代码来发送射线,并且可 ...

  9. Unity3D 脚本手册

    1.private Ray ray;  --定义射线 ray = Camera.main.ScreenPointToRay(Input.mousePosition);  --摄像机发出的射线投射鼠标到 ...

随机推荐

  1. storm启动nimbus源码分析-nimbus.clj

    nimbus是storm集群的"控制器",是storm集群的重要组成部分.我们可以通用执行bin/storm nimbus >/dev/null 2>&1 &a ...

  2. Entity Framework Code-First(9.1):DataAnnotations - Key Attribute

    DataAnnotations - Key Attribute: Key attribute can be applied to properties of a class. Default Code ...

  3. JAVA IO包的整理---------Exception

    EOFException Signals that an end of file or end of stream has been reached unexpectedly during input ...

  4. Centos7安装lnmp环境

    系统版本:centos7 64位 PHP版本:PHP 7.0.21 Nginx版本:1.8.1 MySQL版本:5.5.17 注:1.所有安装都必须放在 /usr/local/src文件夹下 2.添加 ...

  5. KOL运营之——如何与网文作者高效地约稿?

    本文来自网易云社区,转载务必请注明出处. 随着网络文学的发展,影响力逐渐扩大,越来越多的同事在工作中遇到需要和这些作者打交道的时候.对于作者这个群体,很多时候都是只闻其书,不见其人.要跟这样的群体打交 ...

  6. Sharding-JDBC 使用入门和基本配置

    一.什么是Sharding-JDBC Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务.它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理 ...

  7. JSONCPP开发环境搭建

    环境设置 项目地址 https://github.com/open-source-parsers/jsoncpp.git 操作系统 64位 Fedora 24 安装jsoncpp $ git clon ...

  8. Protocol Buffers官方文档(开发指南)

    本文是对官方文档的翻译,然后截取了一篇非常优秀的文章片段来帮助理解,本人英文水平有限,基本都是直译,如果有不理解的地方请参考英文官方文档,参考的文章链接在文章末尾 protocol buffers简介 ...

  9. Glance代码分析

    V2版本的glance-api采用Proxy的方式来构建对象(对象套对象),有点类似装饰器模式,包裹的顺序是 Auth(外层) -> Notifier -> Policy -> Qu ...

  10. 说一说solr在tomcat,jetty上的运行和安装优缺点

    本文是我从别的文章中组合而成的,结合自己实际操作进行了修改. Solr是什么 Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器.Solr提供了比Lu ...