http://www.manew.com/blog-56596-2917.html?_dsign=53b25d5d

unity5.0开发了新的UI系统UGUI,附带的事件系统EventSystem不仅可以用于UI,对于场景中的对象也同样适用。网络上有很多使用说明,但是仅仅是怎么用而已……这篇文章是我翻了无数遍官方手册整理出来的,包括自己的理解,还有官方文档的传送门,也许你会有兴趣。

一、EventSystem对象的说明

当我们在场景中创建任一UI对象后,Hierarchy面板中都可以看到系统自动创建了对象EventSystem,可以看到该对象下有三个组件:EventSystem、StandaloneInputModule、TouchInputModule,后面两个组件都继承自BaseInputModule。

EventSystem组件主要负责处理输入、射线投射以及发送事件。一个场景中只能有一个EventSystem组件,并且需要BaseInputModule类型组件的协助才能工作。EventSystem在一开始的时候会把自己所属对象下的BaseInputModule类型组件加到一个内部列表,并且在每个Update周期通过接口UpdateModules接口调用这些基本输入模块的UpdateModule接口,然后BaseInputModule会在UpdateModule接口中将自己的状态修改成'Updated',之后BaseInputModule的Process接口才会被调用。

BaseInputModule是一个基类模块,负责发送输入事件(点击、拖拽、选中等)到具体对象。EventSystem下的所有输入模块都必须继承自BaseInputModule组件。StandaloneInputModule和TouchInputModule组件是系统提供的标准输入模块和触摸输入模块,我们可以通过继承BaseInputModule实现自己的输入模块。

除了以上两个组件,还有一个很重要的组件通过EventSystem对象我们看不到,它是BaseRaycaster组件。BaseRaycaster也是一个基类,前面说的输入模块要检测到鼠标事件必须有射线投射组件才能确定目标对象。系统实现的射线投射类组件有PhysicsRaycaster, Physics2DRaycaster, GraphicRaycaster。这个模块也是可以自己继承BaseRaycaster实现个性化定制。

总的来说,EventSystem负责管理,BaseInputModule负责输入,BaseRaycaster负责确定目标对象,目标对象负责接收事件并处理,然后一个完整的事件系统就有了。

另外,其实这些说明官方都有提供,这里也就是把英文译成了中文,并整理下,加上自己的理解,有问题的地方请各路神仙多多指教。

官方文档在这里:

http://docs.unity3d.com/ScriptReference/EventSystems.EventSystem.html

二、UGUI中的事件系统

根据第一节中的说明,EventSystem和BaseInputModule是粘在一个对象上的,这两个模块在EventSystem对象上可以直接看到。那么,BaseRaycaster模块呢。。。

其实射线检测,肯定是从摄像机发起的,那么BaseRaycaster模块也一定和摄像机关系一定不简单。

对于UI模块,在Canvas对象下我们可以看到GraphicRaycaster组件。如果Canvas的渲染模式是SceenSpace-Overlay,那么我们是看不到Camera组件的。所以应该是GraphicRaycaster会对UI不同的渲染模式做特殊处理。

因为有GraphicRaycaster组件的原因,Canvas上的所有UI对象,都可以接受输入模块发出的事件,具体事件的处理在第四节说明。

三、场景对象中使用事件系统

场景中的非UI对象,如果想要接收输入模块的事件,一样的道理,也需要给摄像机挂上一个射线检测组件。PhysicsRaycaster, Physics2Draycaster这两个组件分别是用于3D和2D的场景。当然,还需要场景的对象挂了collider射线才检测的到。

其实官方对射线检测也是做了说明的,如果不详读手册是不会发现的,这里是传送门:

http://docs.unity3d.com/Manual/Raycasters.html

如果场景中只有一个射线检测源:When a Raycaster is present and enabled in the scene it will be used by the EventSystem whenever a query is issued from an InputModule.

如果场景中有多个射线检测源:If multiple Raycasters are used then they will all have casting happen against them and the results will be sorted based on distance to the elements.

四、响应事件

1、输入模块可以检测到的事件

StandaloneInputModule和TouchInputModule两个组件会检测一些输入操作,以事件的方式(message系统)通知目标对象,那么这两个组件支持的事件主要有以下:

  • IPointerEnterHandler - OnPointerEnter - Called when a pointer enters the object
  • IPointerExitHandler - OnPointerExit - Called when a pointer exits the object
  • IPointerDownHandler - OnPointerDown - Called when a pointer is pressed on the object
  • IPointerUpHandler - OnPointerUp - Called when a pointer is released (called on the original the pressed object)
  • IPointerClickHandler - OnPointerClick - Called when a pointer is pressed and released on the same object
  • IInitializePotentialDragHandler - OnInitializePotentialDrag - Called when a drag target is found, can be used to initialise values
  • IBeginDragHandler - OnBeginDrag - Called on the drag object when dragging is about to begin
  • IDragHandler - OnDrag - Called on the drag object when a drag is happening
  • IEndDragHandler - OnEndDrag - Called on the drag object when a drag finishes
  • IDropHandler - OnDrop - Called on the object where a drag finishes
  • IScrollHandler - OnScroll - Called when a mouse wheel scrolls
  • IUpdateSelectedHandler - OnUpdateSelected - Called on the selected object each tick
  • ISelectHandler - OnSelect - Called when the object becomes the selected object
  • IDeselectHandler - OnDeselect - Called on the selected object becomes deselected
  • IMoveHandler - OnMove - Called when a move event occurs (left, right, up, down, ect)
  • ISubmitHandler - OnSubmit - Called when the submit button is pressed
  • ICancelHandler - OnCancel - Called when the cancel button is pressed

只要目标对象的mono脚本实现了以上接口,那么输入模块会将检测到的事件通过这些接口通知给目标对象。参考:http://docs.unity3d.com/Manual/SupportedEvents.html

如果你自定义了自己的输入模块,那么以上这些事件肯定是不能用的了。

2、接收输入事件的方式

1)、自行继承接口实现监听

在mono脚本中继承输入模块提供的事件接口,如下图。接口的定义方式也可以查下官方手册,http://docs.unity3d.com/ScriptReference/EventSystems.IBeginDragHandler.html 这边有每一个接口的定义方式,放心大胆地点进去。另外,添加ObjChooseEvent组件的对象,一定要有Collider哦。

2)、 通过EventTrigger组件监听事件

这是一个官方组件。在需要监听事件的对象上,挂上这个组件,然后在Inspector面板展开配置,你会看到这个组件提供了所有输入模块支持的事件类型的监听,如下图。

这种方式的优点是,当你选中一个你要监听的类型,你可以为这个事件类型添加多个监听接口,统一管理,可以清楚的知道到底哪些地方响应了这个事件呢。如果是继承Interface的方式,它将会分散在N个脚本里,一旦出现问题,那查起来一定会很酸爽。

但是这种通过配置的方式,一旦项目多人协作,项目的复杂度起来,这种拖来拽去的配置终究是会有很多问题的,比如某个组件删除,比如响应接口改了个名字~~都会导致配置丢失,而问题又不能及时发现。又或者程序的监听接口因为某些条件而不同。所以也许你会需要第三种方式。

3)、动态添加EventTrigger组件或者修改组件

其实http://www.cnblogs.com/zou90512/p/3995932.html 这位同学的博客对这三种方法都做了很详细的说明。

只不过EventTrigger对外提供的接口不是很友好,导致我们需要添加一个监听,仿佛绕了N了山路弯弯,看着就心情不愉快……反而是这位博主后面说的Button的Click事件的实现方式有点意思……如果项目有需要,也许我们也可以这么做……

五、EventSystem组件提供的一些有意思的接口

其实文档都有http://docs.unity3d.com/ScriptReference/EventSystems.EventSystem.html 只是也许你没有注意。

点击EventSystem对象,你可以看到运行时候的一些详细数据:

变量:

firstSelectedGameObject:这个值可以在面板设置,如果你需要游戏在启动的时候自动选中某个对象,需要鼠标的那一下点击。

currentSelectedGameObject:当前选中的对象,你可以通过这个值判断当前是否鼠标点击在对象上,因为也许你有拖动摄像机的功能,但是你又不喜欢点击某些对象的时候这个功能又被响应,所以通过这个变量判断是一个很好的办法。

接口:

IsPointerOverGameObject:当前鼠标是否在事件系统可以检测的对象上。

SetSelectedGameObject:这个接口也许你会忽略,但是它很棒。因为你点击场景对象的时候,如果不调用这个接口,你的对象是收不到OnSelect事件的,currentSelectedGameObject的值也不会被设置的,必须在点击事件里调用这个接口设置选中对象!

Ex:

public void OnPointerClick(PointerEventData eventData)

{

print ("OnPointerClick...");

currEvent.SetSelectedGameObject(gameObject);

}

不用在场景里找EventSystem对象,EventSystem组件有一个current静态变量,它就是你要的对象,直接EventSystem.current即可使用。

第一次在蛮牛发文章,word中的图片竟然不能直接copy进来使用……

Unity5.0 EventSystem事件系统的详细说明的更多相关文章

  1. Unity5.0 手动激活

    提供Unity5.0.1.f1(32-bit)下载http://pan.baidu.com/s/1bg5sDK 密码 ns75 有时候会发现,用激活工具是激活不了的,这个时候就要手动激活,其实个人觉得 ...

  2. MyEclipse10.0的破解过程详细及图解

    MyEclipse10.0的破解过程详细图解 准备阶段 : 1. 破解软件(网上有下载) 2. JDK软件(免费软件) 开始破解: 1. 关闭MyEclipse 10.0 2. 安装 JDK 然后解压 ...

  3. Unity5.0与Android交互

    1. 目标 1) Unity3D可调用Android Java函数(在.jar中) 2) Java可调用Unity3D函数 3) Unity3D可调用Android C函数(在.so中) 2. 测试环 ...

  4. Erstudio8.0怎么用?Erstudio8.0汉化版详细使用教程

    Erstudio8.0使用教程 打开ERstudio,点击新建出现如图对话框: 选择第一个,表示创建一个新的关系型 数据库模型 这里提一点数据库模型分为relational(关系)和dimension ...

  5. 【Unity】近期整理Unity4.x 项目升级Unity5.0 过程中出现的各种常见问题,与大家共享。

    近期整理Unity4.x 项目升级Unity5.0 过程中出现的各种常见问题,与大家共享. 1:Unity4.x 项目中3D模型其材质丢失,成为"白模"?       解决方式:手 ...

  6. springboot2.0整合logback日志(详细)

    <div class="post"> <h1 class="postTitle"> springboot2.0整合logback日志(详 ...

  7. zabbix3.0.4 邮件告警详细配置

    sendEmail是一个轻量级,命令行的SMTP邮件客户端.如果你需要使用命令行发送邮件,那么sendEmail是非常完美的选择:使用简单并且功能强大.这个被设计用在php.bash perl和web ...

  8. unity5.0新功能-布料、动画系统

    原作者:只待苍霞 这一章讲一下布料系统, 这次的布料系统有很大的改良.Unity4中, 需要对SkinnedMeshRenderer使用SkinnedCloth, 或者对Cloth Renderer使 ...

  9. unity5.0新功能

    原作者 只待苍霞 章节1: 先来两个最关心的新功能, 第一章先讲PBS, 第二章讲光影GI.说到PBS, 首先应该想到的是Unity自带的两个新的Shader, 分别是Standard以及Standa ...

随机推荐

  1. EasyDarwin开源流媒体云平台之EasyRMS录播服务器功能设计

    需求背景 EasyDarwin开发团队维护EasyDarwin开源流媒体服务器也已经很多年了,之前也陆陆续续尝试过很多种服务端录像的方案,有:在EasyDarwin中直接解析收到的RTP包,重新组包录 ...

  2. maven的基本原理和使用

    一.Maven中央存储库 当你建立一个 Maven 的项目,Maven 会检查你的 pom.xml 文件,以确定哪些依赖下载.首先,Maven 将从本地资源库获得 Maven 的本地资源库依赖资源,如 ...

  3. javaweb开发之javaBean

    一.JavaBean简介 JavaBean是使用Java语言开发的一个可重用的组件,在JSP的开发中可以使用JavaBean减少重复代码,使整个JSP代码的开发更简洁.JSP搭配JavaBean来使用 ...

  4. XML 解析错误:找不到根元素

    大家在开发web项目的过程中,可能会遇到“XML 解析错误:找不到根元素”这么一个问题,引起这个问题的原因可能有很多种,在这儿我只是跟大家分享一下我遇到一种情况. 1.项目背景描述 extjs 结合a ...

  5. error LNK1112: module machine type 'X86' conflicts with target machine type 'x64'

    1 这个error是什么原因造成的 cmake默认选择的是x86,即32位的生成子. 2 怎么解决这个error 在cmake ..的时候,在后面加上“-G "Visual Studio 1 ...

  6. 单指令多数据流Single Instruction Multiple Data

    Single Instruction Multiple Data,单指令多数据流)能够复制多个操作数,并把它们打包在大型寄存器的一组指令集,例:3DNow!.SSE. SIMD在性能上的优势: 以加法 ...

  7. HZNU 与班尼特·胡迪一起攻破浮空城 【DP】

    题目链接 http://acm.hznu.edu.cn/OJ/problem.php?id=2264 思路 从终点往起点走 然后每次更新状态 因为要满足 最短路线 所以其实 只能是 往左走,往下走 或 ...

  8. HDU2512 一卡通大冒险 —— 第二类斯特林数

    题目链接:https://vjudge.net/problem/HDU-2512 一卡通大冒险 Time Limit: 2000/1000 MS (Java/Others)    Memory Lim ...

  9. Eclipse配置python环境

    主要分为四步 1.安装java环境 2.在Eclipse下安装Pydev 1)启动 Eclipse,利用 Eclipse Update Manager 安装 PyDev.在 Eclipse 菜单栏中找 ...

  10. XML中CDATA和#PCDATA的区别

    在XML文档中, 能看到“CDATA"的地方有三处: 1)在DTD中,指定标签中某个属性的类型为字符型时,使用CDATA.因为XML解析器会去分析这段字符内容,因而里面如果需要使用>, ...