• NGUI之UICamera控制触摸,鼠标事件


    http://blog.csdn.net/onerain88/article/details/18963539

    . UICamera 功能介绍

    主要包括UI事件的监听,分发,覆盖范围为此Camera渲染的所有GameObject。

    事件源包括:鼠标,触摸,键盘,手柄。

    事件包括:悬停,按下/抬起,选中/取消选中,点击,双击,拖拽,释放,文本输入,Tips显示,滚轮滑动,键盘输入。

    2. UICamera 实现流程

    (1)属性

     

    Event Type:包括UI,World,用于区分UICamera处理UI事件的对象是UI控件还是3D物体。

    EventMask:可以过滤掉一些不需要接受UI事件的对象

    Event Sources:是指需要处理的事件源,比如iPhone可能只需要Touch,PC平台可能还需要Mouse,Keyboard勾选

    Thresholds:是指事件误差的范围,比如Mouse Click是指鼠标的按下和抬起两个事件在UI上的偏移误差不能大于10pixels,当大于10pixels时,则认为不是点击事件!

    Axes and Keys:是指方向键/摇杆,键盘绑定

    (吐槽一下,对于Horizontal这种字符串的设置,如果不小心修改了,就没办法根据字符串找到对应的变量值了,建议改成枚举类型)

    (2)监听和分发

    在Update()中,依次处理 触摸/点击,文本输入,键盘/摇杆输入,Tip。

    其中最主要的就是 触摸/点击 事件的处理了,下面以触摸事件处理ProcessTouches()来分析。

    NGUI封装了一个MouseOrTouch类封装Unity3D中Touch类,主要包括位置,偏移,碰撞到的GameObject,事件标志。

    在UICamera中,缓存着以id为Key,以MouseOrTouch对象为Value的字典对象mTouches,在ProcessTouches()中,通过Unity3D提供的Input.GetTouch()获取到Touch对象,如果是新的触摸点,则缓存在mTouches中,获取当前触摸点(MouseOrTouch对象),对其属性进行计算和设置。

    对于每个触摸对象,都需要通过ProcessTouch(bool pressed, bool unpressed)处理,在这个方法中,主要用于对不同事件的区分和分发。

    pressed和unpressed表示当前触摸对象的当前状态,这里拿常用的点击事件举例,根据对点击事件的理解,我们应该知道此时触摸对象的当前状态分别为pressed=false,unpressed=true,并且此MouseOrTouch对象的touchBegan=false,pressed!=null。

    我们先看pressed=false的处理,这里需要主要的是对当前MouseOrTouch“从开始到现在”偏移量,当这个偏移量大于设置的Mouse Click/Touch Tap时,则取消此次Click事件。

    再看unpressed=true的处理,首先应该确定此MouseOrTouch对象的pressed对象不为null,然后判断当前MouseOrTouch对象的拖拽对象是否等于当前对象,并且当前MouseOrTouch对象的click事件没有在上一步取消掉,并且MouseOrTouch对象的整体偏移量小于设置的Drag值(Thresholds中设置的Mouse Drag/Touch Drag),在这些条件下,则满足“点击事件”,发送给MouseOrTouch对象的pressed对象OnClick消息,此MouseOrTouch对象处理完成!

    (上述分析只是对于“点击事件”,如果要分析其它事件的具体逻辑,可以先根据事件类型确定ProcessTouch()方法的两个参数,然后根据参数在不同分支中分析代码)

    3. 区分多种点击事件

    NGUI中提供了一种对于点击事件的处理,假如我们希望添加自己的点击事件处理,并且区别于NGUI的触摸事件,举例来说,假设我们的场景中的地图和HUD的UI都是可以点击的,这里用一个UIButton和3D Cube模拟场景

     

    对于一次点击事件,如果点击到UI控件上,我们将取消对于自定义事件的逻辑处理;如果没有点击到UI控件上,我们需要判断是否点击到“自定义区域”,假如点击到了,则执行自定义事件的逻辑处理。

    这时我们可以通过UICamera的

    static public bool Raycast (Vector3 inPos, out RaycastHit hit)

    的返回值来确定这次点击事件是否触发了UI事件,如果触发了,则取消对自定义事件的逻辑处理。

     

    (这个方法将场景中所有的UICamera依次遍历判断)

    (PS:这样做虽然相当于做了两次UI碰撞检测,但是避免了判断自定义事件与UI事件调用Update()的顺序问题)

  • 相关阅读:
    Java 集合 — ArrayList
    Java 线程 — ScheduledThreadPoolExecutor
    Java 线程 — ThreadPoolExecutor
    Java 线程 — ThreadLocal
    Java 线程 — ConcurrentLinkedQueue
    Java 线程 — ConcurrentHashMap
    Java 线程 — AbstractQueuedSynchronizer
    Java 线程 — JMM Java内存模型
    Java 线程 — synchronized、volatile、锁
    spring源码 — 三、AOP代理生成
  • 原文地址:https://www.cnblogs.com/123ing/p/4076179.html
Copyright © 2020-2023  润新知