24.总结
24.1 知识点

学习的主要内容

必须要达到的水平

学会举一反三

24.2 核心要点速览
资源包与创建入口
- Asset Store 搜 NGUI → 导入 → 在 Project 里熟悉 NGUI 相关目录(脚本、示例、图集工具入口)。
| 目标 | 操作 |
|---|---|
| 拉出带 Root 的 UI 根 | Project 里 创建 2D UI,UIRoot 上会自动挂 Root,不必先建空物体再手补 |
UIRoot 与分辨率适配
UIRoot 是整棵 UI 的画布根:定基准分辨率,管屏幕变化时如何缩放。
| 模式 | 尺度思路 | 典型场景 |
|---|---|---|
| Flexible | 以像素为准,标称 100px 的控件物理像素不变;窗口拉大显得更小 | PC 可拖窗口、分辨率常变;可配 Min/Max Height、竖屏用宽算、Adjust by DPI(原文建议勾) |
| Constrained | 按 Content 宽高 设计稿比例贴真实屏幕 | 手机/主机全屏;Fit 决定优先保宽 / 保高 / 组合 |
| Constrained On Mobiles | 桌面 Flexible + 移动 Constrained | 多平台一套工程 |
Constrained 下 Fit 组合
| Fit | 大致效果 | 风险或备注 |
|---|---|---|
| 只勾 宽 | 左右铺满设计宽度 | 上下黑边或裁切;原文常配竖屏 |
| 只勾 高 | 上下铺满设计高度 | 左右黑边或裁切;原文常配横屏 |
| 宽+高 都勾 | 按屏与设计宽高比切换保宽/保高 | 一般不裁切,可能有黑边 |
| 都不勾 | 始终铺满视口 | 易裁边,无黑边 |
| 美术 | 全屏底图按 19.9:9 等极限比例多留出血 | 防细长/超宽机露边 |
UIPanel
| 要点 | 说明 |
|---|---|
| 存在意义 | 无 Panel 祖先则子控件默认不渲染;控件归最近的 UIPanel 管 |
| Depth | 面板之间绘制顺序,大的盖小的;两 Panel 同 Depth 会告警 |
| Alpha | 整面板含子节点一起透明 |
| 高级 | Render Q、Sort Order、法线/UV2、Cull、Static 等,合批与 Shader 时动 |
| Anchors | 与 Widget 的 Pivot / Size 一起看分辨率拉伸 |
Clipping
| 模式 | 作用 |
|---|---|
| None | 不裁 |
| Texture Mask | 按贴图形状遮罩 |
| Soft Clip | 矩形裁切 + 柔边 |
| Constrain But Dont Clip | 画面不裁,只缩点击/响应范围 |
EventSystem(相机上的事件侧)
- 用途:把射线命中与 鼠标 / 触摸 / 键盘 / 手柄 接到 UI;没有它点按钮无响应。
| 项 | 说明 |
|---|---|
| Event Type → UI | 按 Widget 深度决定谁吃事件 |
| Event Type → World | 按与主摄像机距离排序 |
| 2D / 3D | 用 2D 或 3D 碰撞体,与相机正交/透视无直接绑定;碰撞器 NGUI → Attach |
| Events go to | 走刚体或碰撞盒链路 |
| Process Events In | Update / LateUpdate,一般默认 |
| Mask / Debug / 阈值 / Axes | 层级过滤、调试、拖拽灵敏度、轴映射;排 bug 常动 Debug |
图集制作
- 目的:
UISprite只吃图集子图;多张小图合一纹理,同材质连续画更易合批。
| 步骤 | 内容 |
|---|---|
| 入口 | NGUI → Open → Atlas Maker(或 Project 右键同菜单) |
| 新建 | New → 选散图 → Create;示例常放 Resources 便于 Load |
| 产物 | Atlas 数据 + 材质 + 合并大纹理 |
| 维护 | Add/Update;X → Delete 删子图 |
常用勾选项
| 项 | 作用 |
|---|---|
| Padding | 子图间隙 |
| Trim Alpha | 去透明废边 |
| PMA Shader | 预乘 Alpha |
| Force Square | 正方形、2 的幂尺寸 |
| View Sprites | 查看已打入的子图 |
UISprite 与 UITexture
| UISprite | UITexture | |
|---|---|---|
| 资源 | 必须图集 | 独立 Texture,大图、全屏底图 |
| Inspector | Atlas + Sprite,Fixed Aspect 锁比例 |
直接绑贴图 |
| Type | Simple / Sliced / Tiled / Filled / Advanced | 类似,含 Filled 等 |
公共 Widget:Pivot、Depth(同 Panel 内排序)、Size / Aspect。
// 同图集换图
uISprite.spriteName = "bk";
// 换图集
uISprite.atlas = Resources.Load<NGUIAtlas>("Atlas/login");
uISprite.spriteName = "ui_DL_anniuxiao_01";
// 大图
uITexture.mainTexture = Resources.Load<Texture>("BK");
UILabel
| Overflow | 行为 |
|---|---|
| Shrink Content | 字随框缩 |
| Clamp Content | 字号固定,超出裁掉 |
| Resize Freely | 框随文字变大 |
| Resize Height | 高度随字,宽度手调 |
- 字体:动态 TTF ↔ NGUI 字体图集(bake 字形,静态大字量更省 DrawCall,见后文)。
- 表现:
Effect阴影/描边;Float spacing;BBCode 颜色、加粗、url等。 - 可点链接:碰撞体 + Open URL On Click 一类脚本。
- 代码:多数改
text。
// BBCode 须先在 Inspector 开启;示例标签:
// [ff0000]颜色[-] [b]粗[/b] [url=...][u]链[/u][/url]
uILabel.text = "内容";
组合控件共通套路
| 步骤 | 内容 |
|---|---|
| 基底 | Sprite / Label / Texture 之一 |
| 功能 | 再挂 Button / Toggle / Input… |
| 交互 | 必须 NGUI 碰撞体,否则射线打不中 |
uIButton.onClick.Add(new EventDelegate(SomeMethod));
uIButton.onClick.Add(new EventDelegate(() => { /* ... */ }));
// Inspector 绑定:被拖选的函数一般为 public
UIButton · UIToggle · UIInput · UIPopupList · UISlider
| 控件 | 制作骨架 | 高频注意 |
|---|---|---|
| UIButton | Sprite → 可选子 Label → UIButton → 碰撞体 | Colors/Sprites 多状态;Notify 可多对象顺序回调 |
| UIToggle | 父 Sprite + 子勾选图 → UIToggle → 碰撞体 | Group 相同=单选;0=独立;State of None 可全不选;读 value |
| UIInput | 底 Sprite + 显示 Label → UIInput → 碰撞体 | onSubmit vs onChange;Saved As 写 PlayerPrefs,一般关 |
| UIPopupList | Sprite + Label → UIPopupList → 碰撞体 | Label 链 SetCurrentSelection;items.Add;无反应查 Font |
| UISlider | 底 → 条 → 滑块,Depth 递增;UISlider 在根上 | 碰撞在底=点条跳;只在滑块=只能拖;value 0~1;onDragFinished |
ScrollBar · UIProgressBar · UIScrollView · UIGrid
| 类型 | 要点 |
|---|---|
| ScrollBar | 多配 UIScrollView,条长随内容变 |
| UIProgressBar | 底+条;纯展示更简单可改用 Sprite Filled;一般不加碰撞体 |
| UIScrollView | NGUI → Create → ScrollView;不自动建 UIRoot;子 Panel Size=视口;关联 ScrollBar 后条由视图驱动 |
| 可拖子项 | Drag Scroll View + 碰撞体 |
| UIGrid | Cell 宽高、Row Limit、Sorting;Constrain to panel 回传布局;动态改子物体后 UpdateScrollbars() |
ScrollView 参数速查
| 参数 | 记忆点 |
|---|---|
| Movement | 横 / 竖 / 自由 / 自定义 |
| Drag Effect | 常用惯性+弹力 |
| Restrict Within Panel | 不勾易少回弹 |
| Cancel Drag if fits | 勾=未溢出不可拖 |
| Scroll Wheel Factor | 非 0 可中键滚 |
Anchor 老版与新版
| 老 UIAnchor | Widget 内嵌 Anchor | |
|---|---|---|
| 参照 | 屏幕或 Container 九宫格 | 默认 向上第一个带 UIPanel 的父 |
| 用途 | 整板贴角、贴边 | 相对父 Panel 边距与拉伸 |
| 关键 | Side、Run Only Once、Relative Offset、Pixel Offset |
Type 无/统一/高级;Execute;统一 L/R/B/T;高级每边可不同目标 |
扩展事件:消息与 Listener / Trigger
- 复合控件的
onClick/onChange盖不住 按下/抬起、悬停、整段拖拽 等细需求。
| 方式 | 适用 | 特点 |
|---|---|---|
消息函数 OnPress OnHover OnClick OnDrag* … |
挂带碰撞体的 MonoBehaviour |
反射查找;每控件一脚本会碎 |
| UIEventListener.Get(go) | 代码里 += |
无则自动加组件;参数更全 |
| UIEventTrigger | Inspector 配 | 适合拖引用;回调常无参 |
var l = UIEventListener.Get(sprite.gameObject);
l.onPress += (go, pressed) => { /* ... */ };
l.onDragEnd += (go) => { /* 摇杆回中、停移动 */ };
DrawCall 与合批
| 概念 | 一句话 |
|---|---|
| DrawCall | CPU 凑齐状态后向 GPU 发一次绘制;多了常卡在 CPU 提交 |
| 图集 | 同 Atlas+材质,且 Widget 深度连续不插队,更易合并提交 |
| UITexture | 多各自绑散图时,常 多次提交,和 Sprite 走图集不同 |
| Label | 动态字大图插在两个同图集 Sprite 中间会打断合批;可把 Label 整体抬高 Depth |
| 查数 | UIPanel Show Draw Call 调层级前后对照 |
| 换内存 | 同一图复制进多场景 Atlas,省批次、涨包体,项目权衡 |
NGUI 字体与动态字体
| Unity 动态字体 | NGUI 字体 | |
|---|---|---|
| 字从哪来 | 运行时栅格进动态大字贴 | 预先 bake 进界面图集 |
| DrawCall | Label 常单独一批 | 可与同 Atlas Sprite 合并 |
| 缺字 | 一般能现造 | 未 bake 的不显示,要回工具补字 |
| 选型 | 变更多、字符不可枚举 | 静态 UI 大字、压批次、美术数字 |
流程:BitmapFont 等导出 fnt/png → NGUI 导入图片做字 → 指定 Atlas;UTF-8 BOM 文本批量选字。
Tween 与 PlayTween
| Tween 组件 | PlayTween | |
|---|---|---|
| 作用 | From/To、Duration、Curve、PlayStyle、TweenGroup | 把 Tween 和 点击/按下/悬停 挂钩 |
| 注意 | On Finished 链公共方法 | 仍要碰撞体;TweenGroup 与 Tween 上 id 一致;Toggle 方向适合按下缩小松开还原 |
| 多组件 | — | 第二个 PlayTween 常需 Inspector Add Component 搜索添加 |
模型与粒子盖住 UI
| 方案 | 做法 | 适用 |
|---|---|---|
| UI 相机直渲 | 模型与 UI 同 Layer,仅 NGUI 相机渲该层;主相机不要再渲 UI 层 | 小装饰、实现快;前后调 z,Depth 不管 3D 网格 |
| RenderTexture | 辅相机按 Layer 渲到 RT → UITexture 显示 | UI 正交 + 模型透视、小窗预览 |
| 粒子在后 | 与 Panel 同 Sorting Layer,在 Renderer 上 提高 Order 或新建更前层 | 粒子被 UI 挡住时 |
杂项与本地化
| 脚本 | 用途 |
|---|---|
| PlaySound | 交互时播 AudioClip |
| KeyBinding | 键盘映射到等价按钮 |
| KeyNavigation | Tab 切焦点;节点要碰撞体和链式关联 |
| Localization | Resources/Localization.txt;Localize 绑 key;LanguageSelection 或 Localization.language;换语言界面 PopupList 等建议动态字体防缺字 |
24.3 面试题精选
本篇从原题库合并同类项,基础 3 / 进阶 2 / 深度 2;Toggle、Slider、ScrollView、图集三件套等细节已写在 24.2,面试时按文补一句即可。
基础题
1. UIRoot:Flexible 与 Constrained 各解决什么问题
题目
两种模式各自以什么为「尺子」缩放 UI?各举一个典型平台或场景。
深入解析
- Flexible:以像素为基准,窗口变大时同样标称像素的控件在屏幕上占比变小,适合 PC 可拖窗口、希望点距相对稳定;可配 Min/Max Height、Adjust by DPI 等。
- Constrained:按设计 Content 宽高整体贴真实屏幕,适合 手机/主机全屏;用 Fit 决定优先保宽还是保高。
- 答清:谁在变分辨率、要不要整画布同比缩放。
答题示例
Flexible:PC 拖窗口,按像素走,拉大窗口 UI 显得更小。Constrained:全屏手游,按设计分辨率缩放贴屏,Fit 管保宽还是保高。
参考文章
- 3.NGUI基础-三大基础组件-Root组件UIRoot
2. Panel Depth、Widget Depth 与 DrawCall / 图集合批
题目
UIPanel.Depth 和子控件 Widget Depth 各管哪一层?两个 Panel 同 Depth 会怎样?DrawCall 偏多时瓶颈常在 CPU 还是 GPU?同图集、深度连续为何更容易少几次提交?
深入解析
- UIPanel.Depth:面板之间谁盖住谁(如 HUD 与弹窗);两 Panel 同值会告警,顺序不稳定。
- Widget Depth:同一 Panel 内绘制顺序,越大越靠前显示。
- DrawCall:CPU 向 GPU 发一次绘制;次数多时往往先卡在 CPU 状态切换与提交。
- 同 Atlas + 深度连续、中间不夹别的材质/动态字贴图,NGUI 更易把多 Widget 合并成更少次提交。
答题示例
Panel 管层与层,Widget 管一层里的前后。Panel 深度别撞车。DrawCall 多是 CPU 在发令。同图集别被别的纹理插队,批次才能并在一起。
参考文章
- 4.NGUI基础-三大基础组件-Panel组件UIPanel
- 19.NGUI进阶-DrawCall
3. UISprite 与 UITexture;可点击还要什么
题目
小图、大图资源形态上怎么选?从 Sprite 做可点按钮,光有 UIButton 够不够?
深入解析
- UISprite:图集子图,适合批量图标、按钮,利于合批与复用。
- UITexture:独立大纹理,适合全屏底图、不便进图集的大图。
- UIButton(或同类脚本)+ NGUI 碰撞体缺一不可;无碰撞体射线打不中,光有脚本点不到。
答题示例
小图走图集 Sprite,特大单张用 Texture。要响应点击必须加 NGUI 碰撞体,不然 UIButton 白挂。
参考文章
- 7.NGUI基础-三大基础控件-Sprite精灵图片
- 9.NGUI基础-三大基础控件-Texture大图控件
- 10.NGUI基础-组合控件-Button按钮
进阶题
1. Constrained 下 Fit 四种组合:黑边与裁切
题目
只勾宽、只勾高、双勾、双不勾时,铺满、黑边、裁切风险各如何?
深入解析
- 只勾宽:保设计宽度进屏,上下可能黑边或裁;常配竖屏。
- 只勾高:保高度,左右可能黑边或裁;常配横屏。
- 双勾:在按宽/按高间切换,一般不裁切,可能有黑边,适合横竖屏切换。
- 双不勾:铺满无黑边,比例不一致时易裁内容;背景要按极限比例留出血(见深度题)。
答题示例
单勾宽保宽、单勾高保高;双勾少裁切可能有黑边;双不勾铺满但可能吃边。背景图要多留一圈。
参考文章
- 3.NGUI基础-三大基础组件-Root组件UIRoot
2. Event Type(UI / World)、碰撞体维度与动态 Label 打断合批
题目
UI 与 World 模式下,谁决定「谁先吃到点击」?「控件离相机远近」在哪一种里才参与排序?Inspector 里 2D/3D 与相机正交透视是什么关系?动态字体 Label 为何能插在两个同图集 Sprite 中间抬高 DrawCall?
深入解析
- UI 模式:按 NGUI Widget 深度;World 模式:按与主摄像机距离,适合世界空间 UI。
- 2D / 3D:指用 2D 还是 3D 碰撞体做射线,与正交/透视无直接绑定;碰撞器用菜单 Attach。
- 动态字:字形渲进另一张大字贴,等价另一套纹理/材质;按深度画时若插在两段同图集 Sprite 之间,合批被切断;可调 Label 整体 Depth 或重排让同图集连续。
答题示例
UI 按深度,World 按离主相机远近。2D/3D 说的是碰撞体类型。动态 Label 是另一张纹理,插队就断批,把字整体挪到一侧或抬高深度。
参考文章
- 5.NGUI基础-三大基础组件-EventSystem组件UICamera
- 19.NGUI进阶-DrawCall
- 20.NGUI进阶-NGUI字体
深度题
1. 全屏背景、极限长宽比与 Root / Fit 的联调
题目
双不勾铺满、单 Fit/双 Fit 出黑边时,背景和关键控件分别要注意什么?
深入解析
- 区分安全内容区与可裁/可拉伸的装饰区:双不勾四角易裁;有黑边时背景要盖住黑边区或接受露色。
- 背景按 19.9:9 一类极限长宽比多留出血。
- 先与程序定主适配轴(横屏保高、竖屏保宽等),美术再出分层稿;关键按钮勿贴理论安全区边缘。
答题示例
先定主适配轴,背景按最长最扁机多留一圈;双不勾时控件别贴边摆。黑边方案要让底图够大盖住。
参考文章
- 3.NGUI基础-三大基础组件-Root组件UIRoot
2. 老 UIAnchor、Widget 内嵌 Anchor;3D 叠 UI 用单相机还是 RT
题目
老 Anchor 与新版内嵌 Anchor 各解决哪类布局?Target 默认指谁?什么情况下模型与 UI 同层、仅 NGUI 相机即可?何时必须 RenderTexture + UITexture?
深入解析
- 老 UIAnchor:整板相对屏幕或 Container 九宫格贴角贴边;
Run Only Once决定是否随分辨率反复对齐。 - Widget 内嵌 Anchor:相对父级 UIPanel 边距与拉伸;Target 默认向上第一个带 UIPanel 的父;高级模式每边可不同参照。
- 单 UI 相机:模型与 UI 同 Layer,仅 NGUI 相机渲该层,主相机勿再渲 UI 层;z 分前后;适合小装饰、实现快。
- RT:辅相机按 Layer 写入 RT,UITexture 显示;适合 UI 正交 + 模型透视、独立光照/后效或与主场景隔离;代价是额外相机与 RT 内存/带宽。
答题示例
老的是整板钉屏幕九宫格,新的是 Widget 跟父 Panel 拉伸贴边,Target 找最近上层 Panel。小模型跟 UI 一层用 UI 相机+z。要透视模型配正交 UI 或小地图隔离,就上 RT。
参考文章
- 17.NGUI基础-Anchor锚点
- 22.NGUI进阶-模型和粒子特效显示在UI之前
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com