Unity中的UGUI源码解析之事件系统(3)-EventData

为了在事件系统中传递数据, Unity提供了EventData相关的类来封装这一类数据. 了解这些结构有助于我们对后面模块的学习.

EventData相关的类有几个, 下面一一介绍.

  • AbstractEventData: 事件数据的抽象基类
  • BaseEventData : AbstractEventData: 基础的事件数据类
  • PointerEventData: BaseEventData: 指针事件数据类
  • AxisEventData: BaseEventData: 轴事件数据类

AbstractEventData

AbstractEventData是事件数据的抽象基类, 内容不多, 提供的接口和属性主要围绕事件数据是否已经被使用过.

在某些逻辑中, 如果事件数据在某些事件处理中被标记为已使用, 则在其它事件中不再处理.

public abstract class AbstractEventData
{protected bool m_Used;public virtual void Reset(){m_Used = false;}public virtual void Use(){m_Used = true;}public virtual bool used{get { return m_Used; }}
}

BaseEventData

BaseEventData是基础的事件数据类,内容也不多, 主要提供了对几个事件系统角色的引用:

  • EventSystem
  • 当前生效的输入模块
  • 当前选中的对象
public class BaseEventData : AbstractEventData
{private readonly EventSystem m_EventSystem;public BaseEventData(EventSystem eventSystem){m_EventSystem = eventSystem;}public BaseInputModule currentInputModule{get { return m_EventSystem.currentInputModule; }}public GameObject selectedObject{get { return m_EventSystem.currentSelectedGameObject; }set { m_EventSystem.SetSelectedGameObject(value, this); }}
}

AxisEventData

AxisEventData是轴事件数据类, 封装了与轴事件相关的数据, 这个轴就是Edit->Project Settings->Input中的那个Axes, 主要在导航事件和位移事件(OnMove)的处理中使用, 提供位移向量和方向.

使用手柄等设备时主要使用这个类型来封装移动事件数据.

public enum MoveDirection
{Left,Up,Right,Down,None
}public class AxisEventData : BaseEventData
{public Vector2 moveVector { get; set; }public MoveDirection moveDir { get; set; }public AxisEventData(EventSystem eventSystem): base(eventSystem){moveVector = Vector2.zero;moveDir = MoveDirection.None;}
}

PointerEventData

接下来就是我们的重头戏, PointerEventData是指针事件数据类, 这也是整个事件系统使用的事件数据的主要部分.

所谓指针事件, 简单说就是触摸和点击, 详情可以参考第一篇概述.

Unity将触摸和点击相关的信息都封装到了PointerEventData中. 并将触摸事件模拟为鼠标左键点击.

InputButton和FramePressState

Unity封装了InputButton, 提供了鼠标几个键的抽象, 通过FramePressState表示几个键的状态.

public class PointerEventData : BaseEventData
{// 分别代表左右中键public enum InputButton{Left = 0,Right = 1,Middle = 2}// 每个键在**当前帧**的状态public enum FramePressState{Pressed, // 按下Released, // 抬起PressedAndReleased, // 按下又抬起NotChanged // 与上一帧相同}// ...
}

基本数据和状态信息

PointerEventData提供了一些属性封装事件的基础和状态等信息.

主要有以下内容:

  • public int pointerId: 键的id, 使用鼠标的情况下, -1代表左键, -2代表右键, -3代表中键, 使用触摸时未测试, 后面有机会测试后补充上.
  • public bool eligibleForClick: 此时事件是否是合格的点击, 后面可以看到, 如果在处理点击事件之前处理了移动事件则会取消此状态导致点击事件无法处理, 这个状态是ScrollRect能够同时滑动和点击的关键.
  • public Vector2 position: 当前触摸或者点击的位置, 屏幕坐标为单位
  • public Vector2 delta: 上次更新到此时更新间的位置变化量
  • public Vector2 pressPosition: 当前(或者最后一次)点击或者触摸的位置
  • public float clickTime: 上次点击或者触摸的时间
  • public int clickCount: 点击次数, 用于短时间内快速多次点击, 比如双击等
  • public Vector2 scrollDelta: 上次更新到此时更新间的滚动变化量
  • public bool useDragThreshold: 是否使用拖拽阈值, 就是之前在上一篇文章介绍的EventSystem组件上设置的值
  • public bool dragging: 当前是否是拖拽状态
  • public InputButton button: 当前事件的按键
  • public bool IsPointerMoving: 上次更新到此时更新间是否发生了移动
  • public bool IsScrolling: 上次更新到此时更新间是否发生了滚动

持有的游戏对象

每次指针数据都会涉及到一些游戏对象, PointerEventData记录了一些对象, 以便使用.

主要有以下属性保存游戏对象:

  • public GameObject pointerEnter: 鼠标进入的对象, 也就是说鼠标指针的位置在某个对象区域内部
  • public GameObject lastPress: 上一个接收到OnPointerDown事件的对象
  • public GameObject rawPointerPress: 原始按下的对象, 不论是否处理OnPointerDown事件, 这里可能会有点疑问, 等后面我们介绍事件处理的时候就明白了
  • public GameObject pointerPress: 当前已接收到OnPointerDown事件的对象
  • public GameObject pointerDrag: 当前已接收到OnDrag事件的对象
  • public RaycastResult pointerCurrentRaycast: 与当前事件关联的 RaycastResult
  • public RaycastResult pointerPressRaycast: 与最后一按下事件关联的RaycastResult
  • public List<GameObject> hovered: 鼠标悬停时, pointerEnter和其所有父节点和祖先节点形成的对象列表
  • public Camera enterEventCamera: 与当前事件相关联的摄像机
  • public Camera pressEventCamera:与最后一按下事件关联的RaycastResult

ToString

与上一篇文章介绍的EventSystem组件的ToString方法配合起来显示当前事件系统状态.

public override string ToString()
{var sb = new StringBuilder();sb.AppendLine("<b>Position</b>: " + position);sb.AppendLine("<b>delta</b>: " + delta);sb.AppendLine("<b>eligibleForClick</b>: " + eligibleForClick);sb.AppendLine("<b>pointerEnter</b>: " + pointerEnter);sb.AppendLine("<b>pointerPress</b>: " + pointerPress);sb.AppendLine("<b>lastPointerPress</b>: " + lastPress);sb.AppendLine("<b>pointerDrag</b>: " + pointerDrag);sb.AppendLine("<b>Use Drag Threshold</b>: " + useDragThreshold);sb.AppendLine("<b>Current Rayast:</b>");sb.AppendLine(pointerCurrentRaycast.ToString());sb.AppendLine("<b>Press Rayast:</b>");sb.AppendLine(pointerPressRaycast.ToString());return sb.ToString();
}

如图所示, 分别是左键, 右键和中键某一帧的状态信息, 这些信息在研究事件系统时能够很好的帮助我们理解.

总结

今天介绍了事件系统的基础之一: 事件数据.

我么知道了Unity是如何定义事件和封装事件数据, 为我们研究接下来的模块打下了基础.

下一篇文章我们会介绍消息系统ExecuteEvents, 看看Unity是如何巧妙的实现常规的显得比较繁重的消息系统.

好了, 今天的内容就是这些, 希望对大家有所帮助.

Unity中的UGUI源码解析之事件系统(3)-EventData相关推荐

  1. Unity中的UGUI源码解析之事件系统(2)-EventSystem组件

    Unity中的UGUI源码解析之事件系统(2)-EventSystem组件 今天介绍我们的第一个主角: EventSystem. EventSystem在整个事件系统中处于中心, 相当于事件系统的管理 ...

  2. Unity中的UGUI源码解析之事件系统(8)-输入模块(中)

    Unity中的UGUI源码解析之事件系统(8)-输入模块(中) 接上一篇文章, 继续介绍输入模块. Unity中主要处理的是指针事件, 也就是在2d平面上跟踪指针设备输入坐标的的事件, 这一类事件有鼠 ...

  3. Unity中的UGUI源码解析之事件系统(9)-输入模块(下)

    Unity中的UGUI源码解析之事件系统(9)-输入模块(下) 接上一篇文章, 继续介绍输入模块. StandaloneInputModule类是上一篇文章介绍的抽象类PointerInputModu ...

  4. Unity中的UGUI源码解析之事件系统(6)-RayCaster(下)

    Unity中的UGUI源码解析之事件系统(6)-RayCaster(下) 接上一篇文章, 继续介绍投射器. GraphicRaycaster GraphicRaycaster继承于BaseRaycas ...

  5. Unity中的UGUI源码解析之图形对象(Graphic)(2)-ICanvasElement

    Unity中的UGUI源码解析之图形对象(Graphic)(2)-ICanvasElement 在上一篇文章中, 我们对整个Graphic部分做了概述, 这篇文章我们介绍ICanvasElement和 ...

  6. elementui组件_elementui 中 loading 组件源码解析(续)

    上一篇我们说了elementui如何将loading组件添加到 Vue 实例上,具体内容见上期 elementui 中 loading 组件源码解析. 这一篇我们开始讲讲自定义指令 自定义指令 关于自 ...

  7. elementui table某一列是否显示_elementui 中 loading 组件源码解析(续)

    上一篇我们说了elementui如何将loading组件添加到 Vue 实例上,具体内容见上期 elementui 中 loading 组件源码解析. 这一篇我们开始讲讲自定义指令 自定义指令 关于自 ...

  8. Qt源码解析之事件系统(一)

    Qt源码解析之事件系统 一.向事件循环里面添加事件 二.QThread里面的事件循环 一.向事件循环里面添加事件 [static] void QCoreApplication::postEvent(Q ...

  9. UGUI源码解析——ContentSizeFitter

    一:前言 ContentSizeFitter继承自ILayoutSelfController,是调整对象自适应的组件,ContentSizeFitter不改变子物体的大小和位置,而是根据子物体(ILa ...

最新文章

  1. 英特尔内存革新助平安云 Redis 云服务降本增效
  2. dom刷新局部元素_JavaScript中DOM和BOM基础
  3. nginx调用PHP有sock方式和端口方式
  4. 【BZOJ1022】小约翰的游戏(博弈论)
  5. SQL server 200 安装问题!
  6. svchost服务(DLL服务)
  7. 【Scratch】青少年蓝桥杯_每日一题_1.1_美国队长盾牌
  8. 像Excel一样使用python进行数据分析(2)
  9. 过程声明与同名事件或过程的描述不匹配_多特征结合的倾斜无人机影像匹配方法...
  10. adb常用命令的使用
  11. TODO:macOS上ThinkPHP5和Semantic-UI集成
  12. JS Math对象(算数、四舍五入、随机数)
  13. 软件测试中python实用技巧,精选22个Python实用技巧,秀技能必备这份技术列表!...
  14. principle中文_principle与principal,长得像,发音还一样!又头疼了!
  15. 菜鸟必须了解的4种后门技术知识!
  16. SHA256算法原理详解
  17. 用手机打开word图表位置很乱_干货 | 论文格式调半天?Word攻略帮你统统都搞定...
  18. python 修图_拿到一张图怎么后期才能更好一点啊?告诉你具体的修图思路
  19. node 脚手架项目,快速删除 node_modules 包的 rimraf 命令
  20. 匿名上位机V7波形显示教程

热门文章

  1. 利用python制作拼图_利用python制作拼图小游戏的全过程
  2. amd同步多线程_首次同步多线程!AMD第三代锐龙3 3300X/3100上市:4核心8线程、PCIe 4加持...
  3. destoon的目录结构
  4. 软件测试工程师必考linux的面试题(老十题)附实拍面试笔试题图
  5. 软件测试压力测试步骤,软件测试员必知!压力测试总共需要几个步骤?思路总结篇...
  6. 分别设计网页访问计数器,会话计数器,访问网站计数器。
  7. 长链接和短链接的区别?为什么要使用短链接?
  8. 深入理解Condition实现原理
  9. (八)hystrix-服务熔断和降级
  10. 今年很难被薪资倒挂了