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

   private void TickModules()
{
for (var i = 0; i < m_SystemInputModules.Count; i++)
{
if (m_SystemInputModules[i] != null)
m_SystemInputModules[i].UpdateModule();
}
}

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

 public void RaycastAll(PointerEventData eventData, List<RaycastResult> raycastResults)
{
raycastResults.Clear();
var modules = RaycasterManager.GetRaycasters();
for (int i = 0; i < modules.Count; ++i)
{
var module = modules[i];
if (module == null || !module.IsActive())
continue;
        module.Raycast(eventData, raycastResults);
} raycastResults.Sort(s_RaycastComparer);
}

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

 private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
{
if (lhs.module != rhs.module)
{
if (lhs.module.eventCamera != null && rhs.module.eventCamera != null && lhs.module.eventCamera.depth != rhs.module.eventCamera.depth)
{
// need to reverse the standard compareTo
if (lhs.module.eventCamera.depth < rhs.module.eventCamera.depth)
return 1;
if (lhs.module.eventCamera.depth == rhs.module.eventCamera.depth)
return 0;
            return -1;
} if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority)
return rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority); if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority)
return rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority);
} if (lhs.sortingLayer != rhs.sortingLayer)
{
// Uses the layer value to properly compare the relative order of the layers.
var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer);
var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer);
return rid.CompareTo(lid);
} if (lhs.sortingOrder != rhs.sortingOrder)
return rhs.sortingOrder.CompareTo(lhs.sortingOrder); if (lhs.depth != rhs.depth)
return rhs.depth.CompareTo(lhs.depth); if (lhs.distance != rhs.distance)
return lhs.distance.CompareTo(rhs.distance); return lhs.index.CompareTo(rhs.index);
}

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

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

  • 按照sortOrderPriority的顺序排序。

  • 按照renderOrderPriority排

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

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

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

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

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

 private static void GetEventChain(GameObject root, IList<Transform> eventChain)
{
eventChain.Clear();
if (root == null)
return;
    var t = root.transform;
while (t != null)
{
eventChain.Add(t);
t = t.parent;
}
}

这段代码一直在点击的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. \阶段4-独挡一面\项目-基于视频压缩的实时监控系统\Sprint2-采集端图像采集子系统设计

    1.在编写程序前有一个流程,思维导图: 初始化:包括初始化摄像头:注册事件到epoll 然后是开始启动采集:一旦开始采集我们的摄像头就会有数据了,它会触发事件处理函数:我们在这里的处理是保存这个图像: ...

  2. 理解setTimeout和setInterval

    setTimeout和setInterval,这两个js函数都是用来定时执行.setTimeout执行一次,setInterval执行多次. 问题出现在今天,使用setInterval是,设置执行速度 ...

  3. 如何使用visual studio 2017创建C语言项目

    使用visual studio 2017创建一个C语言项目,步骤如下: (1)打开Visual Studio 2017环境后出现欢迎界面,如图1所示. 图1  Visual Studio 2017欢迎 ...

  4. ASP.NET MVC实现layui富文本编辑器应用

    先看看视图层 在视图层,使用的是视图助手--HtmlHelper,代替我们网页中传统的表单标签元素,其中的m代表实体模型.通过视图助手,为我们生成id和name属性相同的textarea标签. 备注: ...

  5. .net core 中使用NLog

    在.net standard 2.0.3 和.net core 2.1适用.其他版本的.net 应该也可以. 1.新建一个空白解决方案,再建一个类库 2.安装NLog.Config,会生成一个配置文件 ...

  6. 详细讲解MapReduce二次排序过程

    我在15年处理大数据的时候还都是使用MapReduce, 随着时间的推移, 计算工具的发展, 内存越来越便宜, 计算方式也有了极大的改变. 到现在再做大数据开发的好多同学都是直接使用spark, hi ...

  7. 2017-10-1 清北刷题冲刺班p.m

    一道图论好题 (graph) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图 ...

  8. [Xcode 实际操作]五、使用表格-(4)设置UITableView单元格数据库源

    目录:[Swift]Xcode实际操作 本文将演示如何自定义表格的数据来源. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //首先添加 ...

  9. dorado开发模式下实现动态查询

    使用dorado开发模式,我们可以实现以下开发技巧 开发技巧1.实现动态查询功能: 1. 查询按钮的onClick事件中写入: datasetEmployee.parameters().setValu ...

  10. 洛谷 P1551 亲戚(并查集模板)

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P1551 思路: 很显然地我们会发现,这是一道并查集的模板题,并且是考察了并查集中的”并“和”查“的操 ...