NGUI由ArenMook开发的是一款收费Unity插件($95),多用于做Unity游戏UI系统。作者曾被Unity招安一年开发了官方版本UI系统UGUI,最终与Unity意见相左离开了,但至今他的NGUI仍然维护中,国内游戏NGUI使用率相对更高一些。UIGUI仅开源部分C#代码,核心代码是未开源,NGUI源码完全可自行优化或扩展。
UGUI
Renderer
- CanvasRenderer
Canvas Render Mode
- overlay 无需摄像机,贴着摄像机镜头渲染,永远在最上面
- camera 距摄像机一定距离渲染, 可前后穿插粒子和3d模型等
- worldSpace 融合到3D世界
Canvas Scale Mode
-
Constant Pixel Size:使UI保持自己的尺寸,与屏幕尺寸无关。
-
Scale With Screen Size:根据屏幕尺寸适配UI
a、Match Width Or Height:Match属性是屏幕的宽度和高度对UI大小的适配影响。
b、Expand:缩放时不裁剪UI,当屏幕分辨率和设定不同时,选择变化较小的方向进行缩放。(白话:尽量等比缩放,把你放到屏幕中,完全显示在屏幕中)
c、Shrink:缩放时裁剪UI,当屏幕分辨率和设定不同时,选择变化较大的方向进行缩放。(白话:尽量等比缩放,撑满屏幕的高或宽,会溢出屏幕)
-
Constant Physical Size:使UI元素保持相同的物理大小,与屏幕尺寸无关。
基本设置
如果Render Mode设置为camera,并设置为平行投影,其orthographicSize的含义为屏幕高度的一半, 单位不是px而是unit坐标, 约定设计分辨率为1280x720,则size=3.6(Camera.Size=Screen Height/2/Pixel To Units),上半屏幕刚好可看到3.6个单位大小为1的cube和3.6个100pixel的sprite。
如果Scale Mode设置为Match Width Or Height,取值为1,整体缩放值的是以高来做适配。高度不同分辨率高度完全可见,宽度可视范围不同。
如果Sprite图片的Pixels Per Unit 设置的是100,也就是图片的100个像素对应到一个Unity3D单位。修改 Reference Pixels Per Unit 与 Pixels Per Unit 后,点下 Image 的 Set Native Size来设定图片原始大小。
ui大小 | pixels | spritePixelsPerUnit | referencePixelsPerUnit |
---|---|---|---|
100 | 100 | 100 | 100 |
200 | 100 | 100 | 200 |
50 | 100 | 200 | 100 |
可推导如下公式:
ui rectTransform width/height = pixels/(spritePixelsPerUnit / referencePixelsPerUnit)
VertexHelper
- positions、colors、uv0s、uv1s、normals、tangents
RectTransform
- Achors 锚框
a、四个锚点在重合时,UI尺寸固定,但可能位置会超出父节点。
b、四个锚点全部分开时,UI会随着父节点的尺寸改变而变化。
c、锚点左右两边分开时,UI的height不会随父节点的变化而改变,width会随着父节点的改变而改变。
d、锚点上下两边分开时,UI的width不会随父节点的变化而改变,height会随着父节点的改变而改变。
- Pivot 旋转、缩放等操作注册点
- 只能针对父级结节,不能跨层级锚点
Sorting
- Camera的depth值越小,越先渲染
- 同一个Canvas中,Hierarchy的顺序决定了控件的层级关系,越往下显示越靠前,用SetSiblingIndex等设置深度。
- 不同Canvas用sortingLayer 和 sortingOrder
- z轴排序
- ParticleSystem融合UI用Sorting Order调整层级
Canvas.SendWillRenderCanvas
- layoutRebuildQueue、graphicRebuildQueue(变化的对象在渲染前触发,没有轮询)
Hidden
- Scale=0,Alpha Group=0 没有Mesh,不渲染
- null sprite,Color.a = 0,屏幕外物体,仍然渲染
Batching
- 穿插重叠、旋转等导致打断合批
- z != 0 不合批
- localposition不断更新(即使值没有变化)导致不断重建
- Canvas.BuildBatch更新所有DC:WatigForJob、PutGeometryJobFence、BatchRenderer.Flush*。canvas内任何可视元素的改变(“改变”是指影响UI元素外观的任何变动,包括修改sprite renderer的sprite、transform的position和scale、文本网格的text等。修改Image、Text的color属性,会改变UIVertex.color;修改RectTransform的Size、Anchors、Pivot等,会改变UIVertex.position)都会触发canvas的rebuild,Rebuilding batches是一件很重的事。为了减少batching开销,我们可以合并Sprite、Text等来平衡draw call和batching开销,或把变化的元素提取一个单独Canvas,做到动静分离。
- Mesh合并在C++ Native端做的,融合了多线程操作,大量动态元素合批效率高。
- Mask(Stencil buffer)导致DrawCall上升。换RectMask2D可提升一点性能。
- 修改Image的Color属性实际是修改顶点色,会导致Mesh重建,但材质不变,不会产生额外的DC。如果修改Image的Material的Tint Color属性,不会导致Mesh重建,但修改了Material,会导致多一个DC。
- Frame Debugger (封闭API,无法了解合批细节)
Raycast
- Event、Raycasters基于事件回调机制,效率略高,不需要绑定collider
- Image、Text组件不需要事件触发的将Raycast Target勾去掉
- FullScreen事件
using UnityEngine;
using System.Collections;
namespace UnityEngine.UI
{
public class NonDrawRaycast : MaskableGraphic
{
protected NonDrawRaycast()
{
useLegacyMeshGeneration = false;
}
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
}
}
}
OverDraw
- Image:中间空的边框图不勾FillCenter
- 用PolygonImage贴图更紧凑,Fill rate更低。
Altas
- 保持所有Sprite统一设置贴图属性,否则分离成多张
- Sprite的tag和assetbundle name设置
- Sprite Packer
- Sprite Altas(2017)
基本组件
- Canvas 有世界和屏幕坐标
- Image可以设置Material
- Nav可视化编辑
扩展组件
- LoopScrollRect
- FancyScrollViewt
- 无图文混排 TextMesh Pro
- UnityGUIExtendText
- 文字有简单描边、渐变、投影功能 。其他扩展Unity uGUI Text Outline Shadow
- 没有默认的Tween的Dotween
- 粒子效果层级ParticleEffectForUGUI
- unity-ui-extensions
- UChart
- uGUI-Effect-Tool
- UGUI-Editor
- SoftMaskForUGUI
- UIEffect
- ShinyEffectForUGUI
- unity-psd-ugui
- Unity-SwipeableView
NGUI
Renderer
- MeshRenderer
UIRoot
- Scaling Style
Achors
- Target 可以指定任意GameObject,有设置时序问题。
Sorting
- Camera的depth值越小,越先渲染
- UIPanel的sorting order、widget的depth、RenderQueue共同影响排序.可以很细粒度手工控制。
- ParticleSystem融合UI用Render Queue调整层级
- 3D模型可用RenderTexture或Render Queue融合UI层级
- Mask使用透明度裁剪
Batching
- Mesh Renderer来做渲染,合批在C#层做的
- DrawCall Tool
Hidden
- Color.a = 0 没有Mesh,不渲染
- SetActive(false) 不渲染,保留Mesh
- Scale = 0 保留Mesh,仍然渲染
UIGeometry
- verts、uvs、cols、mRtpVerts
- 堆内存优化
UILabel
- Font.CahceFontForText(动态创建更新FontTexture产生的消耗,当文字color、size等变化都会导致FontTexture扩大或更新)
- Shadow
- Outline/Outline8(Mesh增加)
- Text Mesh Pro插件
UISprite
- Tiled Mode(Mesh增加,节约纹理尺寸)
UIPanel
- UIPanel.FillDrawCall(更新单个DC)
- 触发UIPanel.FillAllDrawCalls(更新所有DC)原因:1.添加或删除元素时,穿插了其他的UIDrawCall。2.添加或删除的元素自成一个UIDrawCall。避免方式:1.尝试让插入的元素合入现有的UIDrawCall。2.Scale=0或者Alpha接近0来隐藏。
- UIPanel.LateUpdate(每帧轮询所有widget)、UICamera.Upate、UIRect.Update、UIRoot.Update
- Clip做裁剪
Altas
- split alpha,shader的处理
Raycast
- 需要绑定collider,通过SendMessage发出事件