NGUI机制

  本文介绍以NGUI的版本是3.6.0版本为,主要介绍NGUI的原理,这个都是本人阅读代码得出的结论,如有错误,欢迎指定

  在NGUI有,有三大基础机制支撑整个NGUI的显示和交互,这三大基础机制分别是:渲染机制事件、消息机制、间格动画。下面将分别介绍这三个机制。

1、渲染机制事件

  • 基础介绍
      NGUI的UIWidget, UIDrawCall,UIGeometry和 UIPanel等基础脚本。
    Ø UIWidget是UI的基础组件(UILabel,UISprite)的基类,含有组件的基本信息(width,Height,color 锚点等)
    Ø UIGeometry是UIWidget的几何数据,记录了顶点坐标,贴图的UVs和颜色等信息
    Ø UIDrawCall是将多个UIWidget的UIGeometry组合起来一起绘制
    Ø UIPanel 用于管理UIWidget、UIDrawCall等,实现界面的渲染裁剪、更新。
    Ø UIRoot UI界面的根目录,用于分辨率适配和事件广播。

  • MeshFilter 和Mesh介绍
      MeshFilter网格过滤器用于从你的资源中获取网格信息(Mesh)并将其传递到用于将其渲染到屏幕的网格渲染器当中。MeshFilter 与 Mesh 联合使用,使模型显示到屏幕上。要想在场景中看到这个网格(mesh),还需要为游戏对象(GameObject)添加一个网格渲染器(MeshRenderer),它应该是自动被添加的。但是如果你将它从你的对象中移除。你必须手动重新添加它。如果网格渲染器(MeshRenderer)不存在,这个网格仍将存在于你的场景中。但是它将不会被绘制。

  • NGUI的渲染机制
      要详细的了解NGUI渲染机制,首先需要打开NGUI隐藏的渲染节点,秘密就在在UIDrawCall.Create(string name) 中的HideFlags.HideAndDontSave, typeof(UIDrawCall));这一行代码。打开在UIDrawCall.cs文件,打开SHOW_HIDDEN_OBJECTS宏定义。就可以看到在渲染过程中,每一个UIDrawCall对应一个把UIDrawCall作为组建的节点【在编辑器可见】如图所示:

    这里写图片描述

    这里写图片描述

      从上面两个图就可以看出来,NGUI渲染实际上就是对通过对Mesh的渲染实现的。整个NGUI的渲染过程就把图片和文字按照一定顺序和规则组织成一系列的Mesh,然后通过Unity自身的渲染流程实现渲染。

  • NGUI的渲染流程
      渲染过程开始的地方UIPanel.LateUpdate:在这个函数有函数调用Updateself 。
      Updateself中:UpdateWidgets:更新UIWeight的位置信息、可见性[含Alpha]、UV信息,是否渲染刷新。UIsprite就是继承于UIWeight的OnFill函数实现多样的化的填装方式(即把UIWeight所需要的数据处理到UIGeometry节点中),如:拉伸、九宫格等等。

    FillAllDrawCalls:全体DrawCall节点刷新。
    FillDrawCall:单个DrawCall节点刷新。
      首先介绍FillDrawCall:顾名思义,这个函数是刷新单个的Drawcall节点
    找到属于这个DrawCall的UIWeight,然后对找到的每个UIWeight处理UV数据的组装,而这个UIWeight的数据就保存在自身的UIGeometry节点上。然后把这个Draw的数据刷新到Mesh上面去即采用UIDrawCall.UpdateGemetry。
      其次是FillAllDrawCalls:顾名思义,这个函数是刷新所有的的Drawcall节点,及重建Drawcall即节点。第一步:删除已经存在的Drawcall节点。第二步:对所有的UIWeight经行排序主要按照深度值和材质。第三步:逐个顺序处理UIWeight,把相邻且具有相同的材质的UIWeight的UIGeometry数据添加到同一个UIDrawCall上来,然后把数据刷新到Mesh上。

2、消息机制

  • 基础介绍
      UICamera:真正做的事情是发送NGUI事件给所有被当前camera渲染的object,camera是UICamera脚本所在的那个。 其实这个脚本做的事情和UI无关。事实上如果你想让游戏里面的object接收OnPress、OnClick、OnDrag等这类事件,你需要把UICamera挂在你的主相机上。游戏场景里面可以有多个UICamera。大多数游戏一个挂在渲染widget的相机上,一个挂在渲染游戏的相机上。UICamera发送以下事件给collider,用他们到自己的脚本里面,只要实现相应的函数即可:
    Ø OnHover (isOver) 发送时机为鼠标悬停(只触发一次)或者离开collider。
    Ø OnPress (isDown) 发送时机为鼠标在collider上按下。
    Ø OnSelect (selected)发送时机为鼠标点击和松开的时候都在同一个object上。
    Ø OnClick ()发送时机和OnSelect一样,但是要求鼠标没有移动特别多。UICamera.currentTouchID表示按下的鼠标哪个键。
    Ø OnDoubleClick ()发送时机为当在四分之一秒内click两次的时候。UICamera.currentTouchID表示按下的鼠标哪个键。
    Ø OnDragStart ()发送时机为OnDrag()事件之前。
    Ø OnDrag (delta) 发送时机为一个object被拖拽。
    Ø OnDragOver(draggedObject)发送时机为其他的object拖拽到他的上面。
    Ø OnDragOut (draggedObject)发送时机为其他的object拖拽出他的上面。
    Ø OnDragEnd ()发送时机为drag事件结束。发送给被拖拽的object。
    Ø OnInput (text)发送时机为输入的时候(在点击选择了一个collider之后)。
    Ø OnTooltip (show) 发送时机为鼠标悬停在一个collider上一段时间没有移动。
    Ø OnScroll (float delta)发送时机为鼠标滚轮滚动。
    Ø OnKey (KeyCode key)发送时机为键盘或者输入控制器被使用的时候。
    事件接受函数如下:

    void OnPress (bool isPressed)
    {
    if (isPressed)
       Debug.Log("I was pressed on!");
    else
       Debug.Log("I was unpressed");
    }
  • 监听和分发
      在Update()中,依次处理 触摸/点击,文本输入,键盘/摇杆输入,Tip。
      其中最主要的就是 触摸/点击 事件的处理了,下面以触摸事件处理ProcessTouches()来分析。
      1. 从Input节点中,获取触摸/点击的信息为Touch类。
      2. 根据Touch类的信息,分析出可能事件。
      3. 通过物理的射线检测即(Physics.RaycastAll)找出来对应UI使用的Collider,并把Collider所在的Gameobject作为触发事件的对象。
      4. 把消息事件转化成按照实现相应的函数调用。
      5. 在控件所对应的脚本中实现对应的函数,便可以收到来自于UICamara的调用,并做相应的处理(如:UIButton)
      6. 把静态的Current变量设置为当前的控件脚本,把使用SentMessage或EventDelegate.Excute再次分发出去。如:UIToggle.OnChange

3、间隔动画Tween

  • 基础介绍
    Ø 间隔动画:对对象的某一个变量,使这个变量在一定时间段内,每一帧按照预先指定曲线变化,从而形成一段动画。如:屏幕颜色的渐变、屏幕抖动、对象的运动等等。
    Ø UITweener :是实现NGUI中间隔动画的基础。间隔动画的基类,所有间隔组建都继承该类,用于执行update()。所有的继承了都需要从Begin开始。继承类中主要函数是OnUpdate,用于处理每帧的更新处理。在Begin开启后,当前脚本状态会被设为true,在运行结束之后,又会设置为false。
    Ø UIPlayTween:这个脚本管理一组Tween脚本的Play,提供了不同的Tirgger,然后在不同的事件函数中触发Play(true)

  • UITweener的继承关系图

    这里写图片描述      

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值