How to Develop a Game
UI System
PublishDate: 2025-06-01 | CreateDate: 2025-06-01 | LastModify: 2025-06-01 | Creator:ljf12825

Unity UI系统是Unity引擎内置的用于构建用户界面的工具集。它基于Canvas(画布)架构,支持制作按钮、文本、图片、滑动条、输入框等各种交互元素

UGUI和NGUI

特性UGUI(Unity GUI)NGUI(Next-Gen UI)
开发方Unity 官方第三方(Tasharen Entertainment)
引入版本Unity 4.6+ 内置Unity 3.x 时期的主流 UI 插件
集成性原生集成,支持 Canvas、EventSystem、Animation 等插件形式,较早期版本需手动集成
渲染系统使用 Unity 内部渲染系统(Canvas)自定义渲染系统,Draw Call 优化依赖面板拆分
编辑器支持所见即所得,Scene View 拖拽 UI早期需要反复预览,后期版本改善较多
多分辨率适配有自动布局系统、Anchor、RectTransform依赖自定义 Anchor 系统
动画支持支持 Unity Animation 和 Animator原生支持有限,需自定义组件
事件系统支持原生 EventSystem(点击、拖拽等)使用自己的事件系统
社区和文档官方支持,Unity 文档齐全社区活跃度下降,文档依赖作者和社区
性能对大型复杂 UI 会产生较多 Draw Call,需要合批优化更早期对 Draw Call 优化做得较极致,但维护成本高
是否推荐使用推荐(Unity 官方支持)不推荐新项目使用(已过时)

NGUI是在Unity官方UI系统还不成熟时的“事实标准”,很多Unity3.x和4.x的项目大量使用
UGUI时Unity官方退出的新UI系统,功能更强大,易于扩展,且原生支持多平台和工具链

CreateUI

UnityUI2.0.0

Canvas

Canvas是Unity中所有UI元素的容器,所有UI控件都必须是Canvas的子对象,否则它们不会被渲染成UI

CanvasInspector

Canvas的渲染模式

Canvas有三种渲染模式,不同模式影响UI的显示方式、渲染顺序以及与摄像机的关系

1.Screen Space - Overlay(屏幕空间覆盖)

2.Screen Space - Camera(屏幕空间摄像机)

3.World Space(世界空间)

Canvas组件的重要属性

Screen Space - Overlay

CanvasScreenSpace-Overlay

默认模式

Screen Space - Camera

CanvasScreenSpace-Camera

World Space

CanvasWorldSpace

CanvasScaler

Canvas通常会搭配CanvasScaler使用,控制UI的缩放和适配,CanvasScaler用于根据不同分辨率、屏幕尺寸,动态调整UI大小,保证UI在不同设备上的一致性

三种缩放模式

1.Constant Pixel Size(固定像素大小)

Constant Pixel Size

参数:

2.Scale With Screen Size(随屏幕尺寸缩放)

Scale With Screen Size

3.Constant Physical Size(固定物理大小)

Constant Physical Size

参数:

Graphic Raycaster

在屏幕空间内把点击(Pointer)或触摸事件,转换成UI元素的响应事件

面板属性:

属性名说明
Ignore Reversed Graphics是否忽略背面 UI 图形(比如被旋转了 180° 的 UI 元素)
Blocking Objects控制是否允许 3D/2D 物体阻挡 UI 点击(比如 3D 模型挡住了按钮)
Blocking Mask用于限制哪些 Layer 的物体会阻挡 UI 射线

工作原理:UI射线检测

当你点击屏幕时,Unity的Event System会:

要让Graphic Paycaster正常工作,必须保证:

Canvas Group

CanvasGroupPanel

控制一组UI元素的整体透明度、交互性和射线响应
用它可以实现:

属性

属性名类型作用
Alphafloat (0 ~ 1)控制透明度,0 = 全透明,1 = 不透明。会影响 UI 的视觉透明交互性(如果 Block Raycasts = true)
Interactablebool是否允许子元素响应交互事件(如点击 Button)
Blocks Raycastsbool是否拦截 UI 射线,决定子元素是否能被点击、拖动等
Ignore Parent Groupsbool是否忽略父级 Canvas Group 的控制(重要属性

Canvas的层级关系

Unity允许UI层级中存在多个Canvas组件,这时,Canvas本身就能作为字节点存在,形成嵌套结构

为什么要用子Canvas

子Canvas主要用于优化性能和分离逻辑

性能优化

如果你有一个排行榜界面,只有当排行榜打开时才需要刷新内容,其他UI不变,这可以这样:

Canvas(主UI)
|——背景UI(静态)
|——Canvas(排行榜) <- 单独Canvas打开时才激活和更新

这样排行榜刷新不会引起整个主UI Canvas的重建批次

UI分区逻辑清晰

把HUD、弹窗、系统提示各放到子Canvas中,方便管理和控制层级、显隐、动画等

父子Canvas的排序 & 显示顺序

排序层控制(Sorting Layer + Order in Layer)

每个Canvas都有:

Canvas HUD(Sorting Layer: UI, Order: 0)
Canvas Popup(Sorting Layer: UI, Order: 10)

Popup会在HUD上方显示,即使它是子物体也一样

RectTransform父子关系的影响

Canvas性能

Canvas API

Properties

属性名类型说明常见用途
renderModeRenderMode渲染模式(Overlay、ScreenSpaceCamera、WorldSpace)决定Canvas如何渲染和视图方式
worldCameraCamera渲染用摄像机(适用于 Camera、World 模式)控制UI投射方向、接收事件
pixelPerfectbool是否启用像素完美对齐(仅限Screen Space)像素风格游戏的UI清晰对齐
planeDistancefloat距摄像机的距离(仅Screen Space - Camera)控制Canvas深度层级
scaleFactorfloat缩放因子(通常由 CanvasScaler 控制)适配不同分辨率
referencePixelsPerUnitfloat每单位像素数,决定图像缩放清晰度确保 UI 图像缩放一致
sortingLayerIDint渲染图层 ID控制 Canvas 渲染层
sortingLayerNamestring渲染图层名称可读性更强的层级控制
sortingOrderint同图层中的渲染顺序,越大越前面控制 UI 显示前后关系
overrideSortingbool是否覆盖父 Canvas 的排序逻辑弹窗、特效UI 的独立排序
targetDisplayint目标显示屏幕编号(用于多显示器)多屏幕UI部署
isRootCanvasbool (只读)是否为根 Canvas判断是否主 Canvas(用于布局判断)
rootCanvasCanvas (只读)所属的顶级 Canvas获取当前 Canvas 的上级主容器
renderOrderint (只读)实际渲染顺序(自动计算)调试 Canvas 渲染先后
pixelRectRect (只读)当前 Canvas 实际的像素渲染区域渲染区域调试
renderingDisplaySizeVector2 (只读)渲染显示区域的像素尺寸获取目标显示区域尺寸
overridePixelPerfectbool是否允许覆盖父Canvas的像素对齐设置子 Canvas 不启用像素对齐时用
additionalShaderChannelsAdditionalShaderChannels指定额外的 shader 顶点数据传输通道用于自定义UI Shader
cachedSortingLayerValueint (只读)当前排序图层的底层缓存值,用于排序计算系统内部优化(一般不手动使用)
normalizedSortingGridSizefloatCanvas 分割的排序网格单元大小高阶排序控制,与 SRP 结合使用
updateRectTransformForStandalonebool在手动 Camera.Render() 时是否自动更新 RectTransform手动渲染UI场景
vertexColorAlwaysGammaSpacebool在使用线性空间渲染时是否强制顶点颜色使用 Gamma 空间传递确保 UI 颜色一致性(线性渲染)

Static Method

方法名返回类型描述常见用途
Canvas.ForceUpdateCanvases()void强制更新所有 Canvas 的布局和绘制内容用于在下一帧前立即刷新 UI 状态(比如修改布局元素后)
Canvas.GetDefaultCanvasMaterial()Material返回一个默认 Canvas 材质,用于普通 UI 元素的渲染如果需要自定义绘制或替换默认材质时使用
Canvas.GetETC1SupportedCanvasMaterial()Material获取或生成支持 ETC1 格式贴图的 UI 材质(主要用于 Android)在使用 ETC1 压缩纹理时提供透明通道支持(Alpha 拆分)

Events

事件名调用时机描述常见用途
preWillRenderCanvasesCanvas 渲染前,最先调用在 Canvas 渲染流程开始前立即触发(早于布局和绘制)在渲染前动态调整 UI 布局、刷新数据
willRenderCanvasesCanvas 渲染前,紧接上一步在 Canvas 渲染流程开始前触发,但晚于 preWillRenderCanvases绑定动画播放、状态更新逻辑、依赖布局结果的修改操作
事件区别和调用顺序
Canvas.preWillRederCanvases -> Canvas.willRenderCanvases -> Canvas 渲染

UnityScripting Canvas

UI Component

通用组件

UICommonComponent

Rect Transform

RectTransform继承自Transform,专门用于2D UI布局。
所有UI元素都依赖RectTransform来定位和缩放

核心属性
属性名类型说明
anchorMinVector2锚点区域左下角(归一化坐标,0~1)
anchorMaxVector2锚点区域右上角
anchoredPositionVector2相对于锚点区域中心的偏移量
pivotVector2本地坐标的参考中心(范围 0~1)
sizeDeltaVector2元素宽高,或拉伸模式下的偏移
rectRect (只读)实际的矩形框(位置、宽高)
localPositionVector3相对于父节点的本地坐标(不推荐直接用于 UI)
Anchor

Anchor(锚点)是RectTransform的关键组成部分,决定了UI元素相对于父物体的位置和尺寸的参考点

Anchor实际上是一对二维坐标:anchorMinanchorMax,每个值都是[0, 1]范围内归一化坐标,表示在父元素矩形中的相对位置

锚点的几种模式 1.固定位置(不拉伸)
当:anchorMin = anchorMax

2.拉伸尺寸(适应父物体) 当:anchorMin != anchorMax

Pivot

pivot(枢轴点)定义的是UI元素自身的参考点(中心点),它决定了:

它的值是一个二维向量,范围在[0, 1]之间,表示相对于自身矩形的位置:

pivot位置说明
(0, 0)左下角
(0.5, 0.5)中心(默认)
(1, 1)右上角
(0, 1)左上角
(1, 0)右下角

布局

布局演示 假设Canvas是1920*1080的全屏UI

RectTransform rt = GetComponent<RectTransform>();

rt.anchorMin = new Vector2(0.5f, 0.5f);
rt.anchorMax = new Vector2(0.5f, 0.5f);
rt.pivot = new Vector2(0.5f, 0.5f);
rt.anchoredPosition = new Vector2(0, 0);
rt.sizeDelta = new Vector2(200, 100);

这个UI元素将被放置在屏幕正中央,宽度为200,高度为100

坐标系层级关系

1.anchorMin / anchorMax决定锚点区域

2.anchoredPosition是相对于锚点区域的中心

3.pivot是UI元素自身的中心点

4.最终位置由这些共同计算得到

实际计算公式(简化版)

最终位置 = 锚点区域中心 + anchoredPosition - pivot * sizeDelta

这个公式说明了设置的位置不是直接坐标,而是围绕锚点和pivot共同计算的结果

AnchorPreSets

RectTransform API

Properties

属性描述
anchoredPosition相对于锚点参考位置的二维坐标,表示此 RectTransform 的**pivot(枢轴点)**的位置。
anchoredPosition3D相对于锚点参考位置的三维坐标,主要用于支持 Z 轴(例如 3D UI 或特殊布局需求)。
anchorMax右上角锚点在父 RectTransform 中的归一化坐标(范围 0~1),例如 (1,1) 表示父物体的右上角。
anchorMin左下角锚点在父 RectTransform 中的归一化坐标,例如 (0,0) 表示父物体的左下角。
drivenByObject如果该 RectTransform 的属性被其他对象驱动(如 Layout 组件),会显示驱动它的对象;否则为 null。常用于调试自动布局。
offsetMax当前矩形右上角相对于右上锚点的偏移值(本地坐标)。可以理解为 TopRight 的偏移。
offsetMin当前矩形左下角相对于左下锚点的偏移值。可以理解为 LeftBottom 的偏移。
pivot当前 RectTransform枢轴点,用归一化坐标表示 (0~1),如 (0.5, 0.5) 表示中心点,(0, 0) 表示左下角。
rect在本地坐标系下计算出的实际矩形区域,是一个 Rect 结构体(包含 x, y, width, height)。只读属性。
sizeDelta表示当前矩形的宽高 相对于 anchor 之间距离的增量值。如果 anchorMin 和 anchorMax 相同,则这个值就是最终尺寸。

Public Method

方法描述
ForceUpdateRectTransforms()强制重新计算 RectTransform 的内部数据(通常在布局改变后使用,用来立即更新布局)。
GetLocalCorners(Vector3[] fourCornersArray)获取该 RectTransform 在本地空间中的四个角的坐标,按顺序为:左下、左上、右上、右下。结果会填充到传入的 Vector3[4] 数组中。
GetWorldCorners(Vector3[] fourCornersArray)获取该 RectTransform世界空间中的四个角的坐标(顺序同上)。
SetInsetAndSizeFromParentEdge(RectTransform.Edge edge, float inset, float size)以父物体的某条边为参考,设置当前 RectTransform 距离该边的偏移值(inset)和自身的尺寸(size)。适用于锚点固定在某一边的场景。
SetSizeWithCurrentAnchors(RectTransform.Axis axis, float size)在指定轴(水平或垂直)上,按照当前锚点设置矩形大小。它会考虑锚点之间的拉伸距离,相对于锚点调整 sizeDelta

Event

事件描述
reapplyDrivenProperties当一个 RectTransform 的某些属性(由外部系统如 Layout、Animation 或代码控制)需要被重新应用时触发的事件。开发者可以订阅这个事件来自定义处理逻辑。

Delegate

委托描述
ReapplyDrivenProperties用于 RectTransform.reapplyDrivenProperties 事件的委托类型,定义了事件回调的签名。

UnityScripting RectTransform

Canvas Renderer

CanvasRenderer是Unity UI系统中挂在每个可见UI上的一个底层组件,负责UI的绘制提交,它是Graphic类的渲染后台

CanvasRenderer是连接UI元素和底层渲染管线的桥梁

CanvasRenderer的作用
功能方向说明
渲染控制负责把 UI 元素的顶点数据、颜色、材质提交给 Canvas 系统渲染
可见性控制控制是否显示(通过 cull, SetAlpha, SetColor 等)
材质支持支持单个或多个材质绘制(比如 SetMaterial, SetPopMaterial
顶点缓存维护每个 UI 元素的 Mesh 数据
Mask 支持与 UI Mask 系统配合使用进行遮罩裁剪处理
CanvasRenderer和UI的绘制流程
UI组件(Image/Text 等)
生成顶点、UV、颜色等数据
传给 CanvasRenderer
CanvasRenderer 将数据提交给 Canvas 系统
Canvas 系统统一批处理渲染
CanvasRenderer API

Properties

属性类型含义用途/说明
absoluteDepthint相对于根 Canvas 的深度值用于判断当前 UI 元素在整个 UI 渲染中的层级。数值越大,越“靠上”渲染。
relativeDepthint相对于父 Canvas 的深度值可用于局部 Canvas 中排序。配合 absoluteDepth 理解 UI 层级渲染顺序。
materialCountint当前可用于渲染的材质数量用于分配和管理 UI 材质。你可以通过 SetMaterial() 为每个 index 设置材质。
popMaterialCountint内部用于 Mask(遮罩)的材质数量这个通常配合 UI Masking 使用(如 Image.maskable = true)。设置 PopMaterial 用于控制遮罩剥离行为。
hasPopInstructionbool是否启用了 “渲染堆栈 pop draw call”PopMaterial 有关。你可以开启它来显式控制何时 pop 遮罩渲染状态。
hasMovedbool如果 UI 位置发生变更,则为 true用于判断当前帧是否需要重新生成 UI 顶点几何。优化 UI 刷新频率用。
cullbool是否剔除当前元素设置为 true 时,这个元素不再渲染(即使它可见)。用于节省性能。
cullTransparentMeshbool如果顶点颜色 alpha 接近 0,是否剔除渲染用于透明 UI 元素的剔除优化。默认为 true,避免无意义绘制。
hasRectClippingbool是否启用了矩形剪裁区域是否启用了 EnableRectClipping(Rect)。常用于 ScrollRect 中的裁剪效果。
clippingSoftnessVector2设置裁剪的“软边缘”范围使裁剪边缘变得平滑渐变,不是硬切。单位像素值,适合美术优化。

Public Method

方法中文解释常见用途
Clear()清除所有缓存的顶点数据自定义 UI 元素重绘前清空数据
DisableRectClipping()关闭矩形裁剪区域让 UI 元素可以渲染到全屏(常见于浮动 UI)
EnableRectClipping(Rect rect)启用矩形裁剪区域,只显示 rect 内内容用于 ScrollRect 滚动列表裁剪或自定义遮罩逻辑
GetAlpha()获取当前的透明度值判断当前透明度状态,常用于动画/过渡控制
GetColor()获取当前设置的颜色一般配合 SetColor 使用,读取当前 UI 颜色
GetInheritedAlpha()获取包括所有父级 CanvasGroup 的总 alpha 值透明度层级继承计算,适合判断是否实际可见
GetMaterial(int index)获取某个索引的材质适合高级渲染管理,如多 Pass 材质
GetPopMaterial(int index)获取 Pop 材质(用于 UI 遮罩的反向操作)用于 UI Mask / Stencil Buffer 中的剪裁恢复逻辑
GetMesh()获取当前用于渲染的 Mesh常用于自定义绘制调试和顶点处理
GetSecondaryTexture(int index)获取指定索引的第二纹理用于多纹理 UI Shader,例如溶解图、遮罩图
GetSecondaryTextureCount()获取当前可用第二纹理数量用于管理复杂 Shader UI 结构
GetSecondaryTextureName(int index)获取指定索引的 Shader 属性名获取传入的纹理对应的 _SomeTexName
SetAlpha(float alpha)设置透明度,会与 UIVertex alphaCanvas alpha 相乘快速设置 UI 淡入淡出、不透明状态等
SetAlphaTexture(Texture tex)_AlphaTex 指定为某个纹理,传给 Shader适用于字体抗锯齿、自定义透明纹理渲染
SetColor(Color color)设置颜色,会与 UIVertex.colorCanvas.color 混合比如红色血条:SetColor(Color.red)
SetMaterial(Material mat, int index)为指定索引设置材质UI Shader 控制,如多 pass 渲染、特效图层等
SetPopMaterial(Material mat, int index)设置 Pop 材质(内部用于 Mask 反剪裁)控制遮罩关闭后的恢复材质
SetMesh(Mesh mesh)设置渲染用的 Mesh,Mesh 必须启用读写你可以自定义顶点图形绘制复杂 UI
SetSecondaryTextureCount(int count)设置可用第二纹理数量Shader 中有多个纹理输入时要提前设置
SetSecondaryTexture(int index, string shaderProp, Texture tex)设置指定索引的纹理及其 Shader 属性名给 UI Shader 传多个纹理,如 _MaskTex, _NoiseTex
SetTexture(Texture tex)设置用于 UI 材质中的主纹理相当于设定 Shader 的 _MainTex,适用于 ImageRawImage 渲染

Static Method

方法名作用常见用途
SplitUIVertexStreamsUIVertex 列表拆分成各个属性数组(位置、颜色、UV、法线、切线)修改顶点颜色、UV、法线等时使用
AddUIVertexStreamUIVertex 中的数据添加到现有的顶点属性列表组合多个顶点来源数据,叠加处理
CreateUIVertexStream将单独的顶点属性数组(位置、颜色、UV等)合成为一个 UIVertex自定义 UI 图形顶点数据,如渐变、闪光、圆形 UI 等

静态方法参数说明

参数名类型含义
vertsList<UIVertex>完整顶点数据流
positionsList<Vector3>每个顶点的位置
colorsList<Color32>每个顶点的颜色
uv0S / uv1SList<Vector4>UV 坐标(第0、1通道)
normalsList<Vector3>法线
tangentsList<Vector4>切线,用于光照方向等
streamList<UIVertex>用于最终生成的合并数据

Event

事件名作用使用场景
onRequestRebuild**(仅在 Editor 模式下)**当 CanvasRenderer 中的数据无效、需要重建时触发编辑器下自定义 UI 编辑、自动刷新组件、响应布局更新等

CanvasRenderer

Image

Image用于在Canvas上渲染2D图像

属性
属性说明
Source Image要显示的图片(Sprite)
Color渲染颜色,会乘上图片原色,可用于变色、淡入淡出
Material自定义渲染材质(通常用于特殊效果,如描边、渐变)
Raycast Target是否响应点击事件(勾选表示能被 GraphicRaycaster 检测)
Maskable是否允许被遮罩裁剪(勾选表示允许)

Image Type

类型描述用途示例
Simple直接绘制整张图片图标、贴图、UI背景
Sliced使用 9 宫格方式拉伸按钮、对话框、面板背景
Tiled将图像平铺(不拉伸)填满区域网格背景、重复纹理
Filled根据百分比填充图像血条、技能冷却、进度圈
Image Type: Simple
Image Type: Sliced
Image Type: Tiled

同上

Image Type: Filled
属性含义
Fill Method填充方式(Horizontal、Vertical、Radial360、Radial180 等)
Fill Origin填充起点(左/右/上/下/中心)
Fill Amount填充比例(0 到 1)
Clockwise是否顺时针填充
性能建议
建议说明
尽量合批使用相同材质和图片可减少 draw call
禁用 Raycast Target如果不需要点击事件,记得取消勾选提高效率
使用 SlicedSimple 更适合可拉伸的 UI 元素,避免失真
Mask 做裁剪可配合小地图/头像/UI 视窗裁剪区域
Image API

Static Properties

属性描述
ussClassName该类型元素默认的 USS(Unity Style Sheets)类名。用于样式表(USS 文件)中选择和定义该类型元素的默认样式。

Properties

属性名描述
image要显示的贴图(TextureTexture2D)。设置后,Image 会使用此纹理渲染,控件大小可能自动适应纹理尺寸。
scaleMode图片的缩放模式,使用 ScaleMode 枚举值(如 StretchToFill, ScaleAndCrop, ScaleToFit)控制图片如何适应控件大小。
sourceRect指定贴图中哪一部分作为源区域显示,使用左上角为参考点的坐标和尺寸(单位为像素)。
sprite显示的精灵(Sprite 类型)。这是 UI Toolkit 中推荐的图像显示方式,比原始 Texture 更灵活。
tintColor渲染图片时使用的着色颜色(默认为白色,设置为其他颜色可以改变图片颜色)。
uv图片的 UV 坐标范围,基于左下角为原点(通常用于手动设置 UV 区域,控制显示纹理的哪一部分)。
vectorImage用于显示的矢量图(VectorImage 类型,SVG 样式的图像)。适合需要分辨率无损缩放的图标或 UI 图案。

UnityScrpting Image

UI Element

Panel

Panel是用来组织、分组、控制一组UI元素的容器,是UI架构中最基本的结构单位

本质上是一个普通的GameObject

Panel = GameObject + RectTransform + Other Optional Component

常见用途

用途说明
UI 分组容器将一组相关的 UI 元素包在一起(如背包、商店、设置等)
背景视觉层给 UI 添加一个背景板(通常使用半透明黑色)
控制显示/隐藏通过 SetActive() 控制整组 UI 显示与否
蒙版裁剪配合 MaskRectMask2D 使用,裁剪子内容
动画过渡面板之间切换时做位移、渐变等 UI 动画
局部布局控制配合 LayoutGroup 使用,控制子元素的自动排列

Image

Image = RectTransform + Image
组件Image不能脱离RectTransform和CanvasRenderer
Image组件见上

Raw Image

Raw Image = RectTransform + Canvas Renderer + Raw Image

RawImagePanel

Raw Image是Unity UI中用于直接显示Texture的组件,区别于Image显示SpriteRawImage更灵活,适合直接显示非Sprite类型的纹理

Image vs RawImage

方面RawImageImage
显示资源类型TextureSprite
是否支持 9 切片不支持支持
适合用途视频播放、动态纹理显示、非 Sprite 纹理UI 图标、按钮、九宫格背景
是否自动处理边缘不支持支持切片自动拉伸

Text(Legacy)

UGUI中最早期的文本显示方式之一,Legacy代表它已经被新的系统所取代,但它依然存在于Unity中,作为一种兼容性方案

TextPanel

Text是Unity UGUI系统(UnityEngine.UI.Text)中的标准UI组件,用来在Canvas上显示简单的2D文本

基本属性

属性名说明
Text要显示的字符串
Font使用的字体(.ttf)资源
Font Style字体样式(Normal / Bold / Italic)
Font Size字号大小(整数)
Line Spacing行间距倍数
Rich Text是否启用 <b>,<i> 等富文本语法
Alignment对齐方式(左中右 / 上中下)
Align By Geometry按几何对齐
Horizontal Overflow超出边框时的处理方式(Wrap(换行)/Overflow(溢出)
Vertical Overflow同上,垂直方向 (Truncate/Overflow)
Best Fit是否自动缩放字体以适应文本框大小
Color文本颜色
Material可替换字体材质(如实现描边/阴影)
Raycast Target是否参与事件响应(一般设为 false 提升性能)
Raycast Padding用于扩大或缩小UI元素对射线检测(点击、触摸等交互)的响应区域
Maskable可被遮罩剔除

工作流程

Text(Legacy)的渲染流程大致如下:

Text(Legacy)的缺点

问题说明
清晰度差字体在不同分辨率下可能模糊(Bitmap-based)
无动态字形支持不支持多语言自动扩展字体图集
没有高级排版功能不支持富排版、嵌入图标、文本裁剪等高级功能
不支持富样式难以实现多颜色、高级描边、背景等需求
性能低每次修改文本都会重新生成 UI 顶点,占 GC 和 CPU

性能提升

Text(Legacy) API

Properties
属性名类型说明
alignByGeometrybool是否根据字形几何范围对齐,而非字形度量(更精确的水平对齐)。
alignmentTextAnchor文本相对于 RectTransform 的对齐方式(左中右,上中下等)。
cachedTextGeneratorTextGenerator缓存的文本生成器,用于渲染当前可见文本。
cachedTextGeneratorForLayoutTextGenerator缓存的文本生成器,用于布局计算。
flexibleHeightfloat布局系统调用,表示布局弹性高度。
flexibleWidthfloat布局系统调用,表示布局弹性宽度。
fontFont使用的字体资源。
fontSizeint字体渲染大小(像素)。
fontStyleFontStyle字体样式,如正常、斜体、粗体等。
horizontalOverflowHorizontalWrapMode水平溢出模式(Wrap 或 Overflow),控制文本是否换行。
layoutPriorityint布局系统调用,布局优先级。
lineSpacingfloat行间距,相对于字体行高的比例,1为正常。
mainTextureTexture字体纹理,用于渲染字体。
minHeightfloat布局系统调用,最小高度。
minWidthfloat布局系统调用,最小宽度。
pixelsPerUnitfloat (只读)字体缩放的像素单位,描述字体渲染的像素密度。
preferredHeightfloat由文本生成器计算的理想高度。
preferredWidthfloat由文本生成器计算的理想宽度。
resizeTextForBestFitbool是否允许文本自动调整大小以适应容器。
resizeTextMaxSizeint自动调整时允许的最大字体大小。
resizeTextMinSizeint自动调整时允许的最小字体大小。
supportRichTextbool是否支持富文本格式(例如 <b>, <i>, <color> 标签)。
textstring当前显示的文本内容。
verticalOverflowVerticalWrapMode垂直溢出模式,控制文本超出垂直边界时的处理方式(裁剪或溢出)。
Public Method
方法名说明
CalculateLayoutInputHorizontal由布局系统调用,用于计算水平布局输入(如宽度需求)。
CalculateLayoutInputVertical由布局系统调用,用于计算垂直布局输入(如高度需求)。
FontTextureChangedFontUpdateTracker 调用,当字体纹理更新时触发的回调。
GetGenerationSettings便捷函数,用于生成并填充文本生成器(TextGenerator)的设置参数。
Protected Method

OnDisable

Static Method

GetTextAnchorPivot 提供一个便捷方法计算锚点向量偏移量

UnityScrpting Text(2019.1)

Button(Legacy)

Unity早期标准控件(UnityEngine.UI.Button)

Button(Legacy) = `Rect Transform` + `Canvas Renderer` + `Image` + `Button`
  |__ Text(Legacy)

ButtonCantAddTextComponent

Button组件只能绑定一个Graphic来做交互反馈,比如颜色变化、高亮、禁用状态
这个Graphic是通过Button.targetGraphic这个字段指定的,通常是绑定在同一个GameObject上的ImageRawImage
Unity的默认交互逻辑只能作用于一个

Button(Legacy)Panel

Panel Properties

Button的继承结构

UIBehaviour
|___ Selectable
          |___Button

Selectable提供了核心交互逻辑:

Button在此基础上扩展了:

Button的点击事件流程(底层)

1.场景中有EventSystem + GraphicRaycaster 2.鼠标点击UI Canvas上的对象 3.GraphicRaycaster计算哪个UI元素被点击 4.被点到的UI触发IPointerClickHandler接口 5.Button继承这个接口,调用.onClick.Invoke()

Button示例

基础绑定 + 点击回调
using UnityEngine;
using UnityEngine.UI;

public class ButtonExample : MonoBehaviour
{
  public Button myButton;

  void Start() => myButton.onClick.AddListener(OnButtonClick);

  void OnButtonClick() => Debug.Log("Click!");
}
动态创建按钮 + 设置点击事件
GameObject buttonObj = new GameObject("MyButton", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button));

Button btn = buttonObj.GetComponent<Button>();
btn.onClick.AddListener(() => Debug.Log("动态按钮点击"));
控制按钮状态变化
myButton.interactable = false;

myButton.colors = new ColorBlock
{
  normalColor = Color.white, 
  highlightedColor = Color.yellow, 
  pressedColor = Color,red, 
  disabledColor = Color.gray, 
  colorMultiplier = 1f, 
  fadeDuration = 0.1f
};

自定义扩展

可以通过接口实现更复杂的行为

接口功能
IPointerEnterHandler鼠标进入时触发
IPointerExitHandler鼠标离开时触发
IPointerClickHandler鼠标点击时触发
ISubmitHandler键盘回车时触发(按钮聚焦状态下)
public class MyButtonEx : MonoBehaviour, IPointerEnterHandler
{
  public void OnPointerEnter(PointerEventData eventData) => Debug.Log("鼠标进入按钮");
}
高级交互

原始Button不支持长按、双击、右键等高级操作,可以通过扩展EventTrigger或实现接口自己处理,或自定义实现Button组件

Dropdown = RectTransform + Canvas Renderer + Image + Dropdown
  |___Label // 当前选中项
  |___Arrow // 小箭头实现
  |___Template = RectTransform + Canvas Renderer + Image + Scroll Rect // 下拉菜单模板
        |___Viewport
        |      |___Content
        |             |___Item = RectTransform + Toggle
        |                   |___Item Background
        |                   |___Item Checkmark
        |                   |___Item Label
        |___Scrollbar = RectTransform + Canvas Renderer + Image + Scrollbar
                |___Sliding Area
                           |___Handle

DropdownPanel

属性名说明
Template展开后的菜单列表的模板(Template)
Caption Text当前选项显示的 Label 文本组件
Caption Image当前选项显示的 Image(可选)
Item Text下拉项显示用的 Text
Item Image下拉项使用的图片(可选)
Options所有的选项,Dropdown.OptionData 列表
Value当前选中项的索引
Alpha Fade Speed下拉列表打开或关闭时,列表的透明度变化速度
OnValueChanged回调事件(当选项改变时触发)

Scroll Rect Panel

Dropdown上的Scroll Rect是专用于Dropdown的,区别于通用的Scroll Rect

ScrollRectPanelofDropdown

组件/属性说明
Content要滚动的内容(通常是一个RectTransform,里面包含所有需要滚动的元素)
Viewport可视区域(显示区域),内容超出部分会被裁剪
Horizontal/Vertical是否开启水平或垂直滚动
Movement Type滚动行为类型:
    - Unrestricted内容滚动无限制,超出视口可自由移动
    - Elastic弹性滚动,拖拽到边界时会有弹回效果
    - Clamped内容滚动被限制在边界内,无法拖出视口之外
Elasticity弹性系数,决定弹性滚动的“软硬度”
Inertia惯性开关,决定拖拽释放后内容是否继续滑动
Deceleration Rate惯性减速度,惯性滚动速度衰减快慢
Scroll Sensitivity鼠标滚轮或触控滑动的灵敏度
OnValueChanged滚动事件
工作原理

Viewport

示例

创建一个Dropdown并监听选择变化

using UnityEngine;
using UnityEngine.UI;

public class DropdownExample : MonoBehaviour
{
  public Dropdown myDropdown;

  void Start()
  {
    myDropdown.onValueChanged.AddListener(OnDropdownValueChanged);

    myDropdown.options.Clear();
    myDropdown.options.Add(new Dropdown.OptionData("选项 A"));
    myDropdown.options.Add(new Dropdown.OptionData("选项 B"));
    myDropdown.options.Add(new Dropdown.OptionData("选项 C"));

    myDropdown.value = 0;
  }

  void OnDropdownValueChanged(int index)
  {
    Debug.Log("当前选择索引:" + index);
    Dubug.Log("当前选择内容:" + myDropdown.options[index].text);
  }
}

扩展

用法说明
动态加载选项用代码控制 options 数据源,比如从配置文件读取
多级联动比如:国家 -> 城市,选择国家后动态更新城市列表
自定义表现替换 Item 的 Toggle 结构,实现自定义布局或图标

API

Properties

名称类型说明
optionsList<Dropdown.OptionData>Dropdown 的所有选项列表
valueint当前选中选项的索引(从 0 开始)
captionTextText用于显示当前选择文本的 UI Text 组件
captionImageImage显示当前选择图片的 Image 组件(可选)
itemTextTextDropdown 选项模板中 Item 的文本组件
itemImageImageDropdown 选项模板中 Item 的图片组件
templateRectTransformDropdown 选项列表模板(包含 Viewport 等)

Event

名称类型说明
onValueChangedDropdown.DropdownEvent选中项改变时触发,带选中索引

Method

名称签名说明
ClearOptions()void ClearOptions()清空所有选项
AddOptions(List<string>)void AddOptions(List<string> options)添加字符串选项列表
AddOptions(List<Sprite>)void AddOptions(List<Sprite> options)添加图片选项列表
AddOptions(List<Dropdown.OptionData>)void AddOptions(List<Dropdown.OptionData> options)添加 OptionData 列表
RefreshShownValue()void RefreshShownValue()刷新当前显示的选项文本和图片
Show()void Show()展开下拉列表
Hide()void Hide()关闭下拉列表

Input Field(Legacy)

Input Field是Unity中用于接收用户输入的UI组件,主要用于文本输入(如用户名,密码,聊天框等)

InputField
|—— Palceholder(Text或TMP_Text)
|__ Text

Input Field Panel

InputFieldPanel

属性描述
Text Component用户输入文字组件
text当前输入的字符串
placeholder占位文字组件(Text 或 TMP_Text)
characterLimit输入字符数限制
contentType内容类型(如密码、整数、电子邮件等)
lineType单行或多行
inputType是否隐藏输入字符(如密码)
keyboardType移动端的虚拟键盘类型
readOnly是否只读
caretBlinkRate光标闪烁速度
Custom Caret Color自定义光标颜色
Hide Mobile Input隐藏移动设备键盘上方的原生输入框
selectionColor选中文本的背景色
should Activate OnSelect当InputField被选中时,是否自动激活并弹出键盘
On Value Changed当用户每次修改输入内容时调用(每个字符变动都会触发)
On Submit当用户提交输入时触发即按下回车键时
On End Edit当输入框失去焦点或用户按下回车键时触发

API

Properties
属性名类型说明
textstring当前输入框中的文本内容
textComponentText用于显示文本的 UI 组件
placeholderGraphic占位符(提示文本)组件
characterLimitint最大输入字符数,0 表示不限制
contentTypeContentType输入内容类型(标准、密码、数字等)
inputTypeInputType输入显示方式(标准、密码隐藏等)
keyboardTypeTouchScreenKeyboardType移动端软键盘类型
characterValidationCharacterValidation字符校验规则
multiLinebool是否支持多行输入
lineTypeLineType输入框的换行方式
readOnlybool是否只读
onValidateInputFunc<string, int, char>自定义输入字符验证回调
caretPositionint当前光标位置
caretWidthint光标宽度(像素)
caretBlinkRatefloat光标闪烁速度(次数/秒)
caretColorColor光标颜色
customCaretColorbool是否使用自定义光标颜色
selectionColorColor文本选中时的背景色
selectionAnchorPositionint选中起点
selectionFocusPositionint选中终点
shouldHideMobileInputbool是否隐藏移动端原生输入框
touchScreenKeyboardTouchScreenKeyboard当前软键盘实例
isFocusedbool输入框当前是否获得焦点
wasCanceledbool输入是否被取消(如按返回键)
onValueChangedUnityEvent<string>输入内容改变时触发
onEndEditUnityEvent<string>输入结束时触发(失焦或按回车)
asteriskCharchar密码输入时显示的字符(默认是 *
Public Methods
方法名说明
ActivateInputField()激活输入框,开始处理输入事件(获得焦点,弹出软键盘)
DeactivateInputField()取消激活输入框,停止处理事件;如果输入未取消,会发送提交事件
ForceLabelUpdate()强制立即刷新文本显示(重新计算光标位置和可见文本)
GraphicUpdateComplete()(接口方法)通知画布图形更新完成
LayoutComplete()(接口方法)通知布局更新完成
MoveTextEnd()将光标移动到文本末尾
MoveTextStart()将光标移动到文本开头
OnBeginDrag()处理开始拖动事件,判断是否监听拖动
OnDeselect()处理失去焦点事件
OnDrag()处理拖动事件
OnEndDrag()处理拖动结束事件,停止监听拖动
OnPointerClick()处理指针点击事件
OnPointerDown()处理指针按下事件
OnSubmit()处理提交事件(通常是按回车或软键盘上的提交键)
OnUpdateSelected()处理选中更新事件(持续输入、光标移动等)
ProcessEvent()内部辅助函数,用于处理输入事件
Rebuild()重建输入框几何体(光标、选中高亮等)
SetTextWithoutNotify()设置输入框文本内容但不触发 onValueChanged 事件,常用于程序内部修改文本时避免事件递归触发
Protected Methods
方法名功能说明
Append(char c)在输入框当前文本末尾追加一个字符。
ClampPos(ref int pos)限制传入的光标或选择位置,保证不超过文本长度范围。
GetCharacterIndexFromPosition(Vector2 pos)根据鼠标/指针位置计算对应文本中的字符索引。
KeyPressed(Event evt)处理键盘事件,根据按键执行对应动作(输入、删除、光标移动等)。
OnDisable()MonoBehaviour 生命周期函数,输入框禁用时调用(做清理等)。
OnFocus()输入框获得焦点时初始化相关属性,准备输入。
SelectAll()选中输入框内所有文本,通常用于快捷键 Ctrl+A 操作。
SendOnSubmit()触发提交事件(相当于用户确认输入,如按回车)。
UpdateLabel()刷新显示的文本内容,更新 UI 视图(光标和选区位置)。
Validate(string text, int charIndex, char addedChar)对输入的字符进行校验(依据 characterValidation 设置)。
Delegates
属性名类型作用
onValidateInputInputField.OnValidateInput自定义每个输入字符的校验

TextMeshPro(TMP)

TextMeshPro是Unity提供的高级文本渲染系统,相比传统的UI.TextTextMesh,它提供了:

TMP组件类型

组件名称用途说明
TextMeshPro (3D)用于3D世界的文本渲染(替代 TextMesh
TextMeshProUGUI (UI)用于UI Canvas的文本渲染(替代 UI.Text

TMP Importer

TMP Importer

TMP Importer是Unity第一次导入TextMeshPro包时自动弹出的一个向导窗口,也可以手动从菜单中打开
它的作用是:

何时会看到TMP Importer
TMP Importer提供的资源内容
内容说明
Default Font Asset默认使用的字体(LiberationSans SDF)
Default Material Presets支持描边、阴影的材质
TMP Settings.asset全局设置配置
ShadersTMP 的渲染器使用的 SDF Shader
Examples & Extras(可选)示例场景、脚本、UI 风格演示等

TMP vs Text(Legacy)

功能/特性Unity UI.TextTextMeshPro
清晰度高(SDF)
富文本支持有限强大
图文混排
字体控制基本精细
性能(大批量)
动态字体加载支持

SDF字体 TMP使用SDF来实现高质量的文本缩放和效果(描边、投影)

Text(TMP)

TMPTextPanel_1 TMPTextPanel_2

基础设置区
Main Settings
Extra Settings
Material Inspector

Toggle

结构

Toggle = Rect Transform + Toggle
|___Background(Image):勾选框的背景
|        |___CheckmarkImage):√
|___Label(Text):名称

Toggle Panel

TogglePanel

属性名类型说明
isOnbool当前是否勾选,true 表示已选中
onValueChangedUnityEvent<bool>状态切换时的回调,传入参数为新的状态
interactablebool是否可以被点击
graphicGraphic勾选图像(Checkmark)
groupToggleGroup所属的 ToggleGroup(用于单选)
Toggle TransitionToggle Transition状态切换时的视觉过渡效果

示例

获取并监听Toggle状态
using UnityEngine;
using UnityEngine.UI;

public class ToggleExample : MonoBehaviour
{
  public Toggle myToggle;

  void Start()
  {
    myToggle.onValueChanged.AddListener(OnToggleChanged);
  }

  void OnToggleChanged(bool isOn) => Debug.Log("当前 Toggle 状态" + isOn);

}

Toggle Group(单选组)

ToggleGroup组件用于实现多个Toggle的单选功能,类似于网页中的radio button

设置方法:
1.创建一个空物体并挂载ToggleGroup
2.将多个Toggle拖入该物体并在Inspector中的Toggle组件上设置Group为这个ToggleGroup
3.每次只能勾选一个Toggle

public ToggleGroup toggleGroup;

void GetSelectedToggle()
{
  Toggle selected = toggleGroup.ActiveToggles().FirstOrDefault();
  if (selected != null) Debug.Log("当前选中项: " + selected.name);
}

API

Properties
属性名类型说明
graphicGraphic受状态影响的图像,通常是用于显示勾选标记的 CheckmarkImage 或其他 Graphic)。
groupToggleGroup当前 Toggle 所属于的 ToggleGroup,用于实现“单选”逻辑。
isOnbool当前 Toggle 是否被选中,true 表示“开”;也可用于代码设置状态。
onValueChangedUnityEvent<bool>当 Toggle 状态发生改变时触发的事件回调,参数是新的状态(true/false)。
toggleTransitionToggle.ToggleTransition状态切换的视觉过渡方式,枚举类型:NoneFade(淡入淡出)。
Public Methods
方法 / 接口类型说明
GraphicUpdateComplete()ICanvasElement 接口方法图形更新完成时被调用(Canvas 渲染流程的一部分)。通常无需手动调用。
LayoutComplete()ICanvasElement 接口方法布局更新完成时调用,确保组件根据布局正确显示。
Rebuild(CanvasUpdate update)ICanvasElement 接口方法当 UI Canvas 需要重建时被调用,用于更新 Toggle 的布局或图形状态。
OnPointerClick(PointerEventData eventData)IPointerClickHandler 接口方法当 Toggle 被鼠标点击或触控点击时触发。会自动切换 isOn 状态并触发 onValueChanged
OnSubmit(BaseEventData eventData)ISubmitHandler 接口方法当用户按下“提交键”(如 Enter)时触发(用于键盘/手柄操作 UI)。
SetIsOnWithoutNotify(bool value)自定义方法设置 Toggle 状态但不触发 onValueChanged 回调,适合你在代码中手动切换状态但不希望触发监听器时使用。
Protected Mehtods
方法说明
OnDisable参照MonoBehaviour.OnDisable

Slider

结构

Slider = Rect Transform + Slider
|___Background(Image):滑动条颜色(不可变部分)
|___Fill Area:包裹Fill区域
|       |___Fill(image):实际充填区域,随着值的改变而拉伸/缩放
|___Handle Slide Area:可滑动范围的区域容器
             |___Handle(image):可拖动的滑块,通常是个图标或者圆点

Slider Panel

SliderPanel

API

Properties
属性类型说明
directionSlider.Direction滑动条的方向,从最小值到最大值的滑动方向。
可选:
LeftToRight
RightToLeft
BottomToTop
TopToBottom
fillRectRectTransform指定一个 RectTransform,作为滑动条的填充区域。滑动值变化时会调整此区域的大小。
handleRectRectTransform指定滑块的 RectTransform,用于显示可拖动的手柄。
maxValuefloat滑动条允许的最大值。
minValuefloat滑动条允许的最小值。
valuefloat当前的滑动值。可以手动设置,会同步更新滑块位置和填充。
normalizedValuefloat (只读/可设)当前值归一化后(范围 0 到 1)的表示。设置它可以等价于设置 value
onValueChangedUnityEvent<float>value 改变时触发的回调事件。可以在 Inspector 中指定函数响应变化。
wholeNumbersbool是否只允许整数值。勾选后即使你滑动到小数位置,也会自动取整。

示例:设置Slider参数

public Slider mySlider;

void Start()
{
  mySlider.minValue = 0;
  mySlider.maxValue = 100;
  mySlider.value = 50;;
  mySlider.wholeNumbers = true;

  mySlider.onValueChanged.AddListener(OnSliderValueChanged);
}

void OnSliderValueChanged(float val) => Debug.Log("当前值" + val);
Public Methods
方法名来源接口 / 基类说明
FindSelectableOnDown()Selectable返回下方的可选 UI 元素(用于键盘/手柄导航)。
FindSelectableOnUp()Selectable返回上方的可选 UI 元素。
FindSelectableOnLeft()Selectable返回左侧的可选 UI 元素。
FindSelectableOnRight()Selectable返回右侧的可选 UI 元素。
GraphicUpdateComplete()ICanvasElement在 UI 图形重绘完成时调用。
LayoutComplete()ICanvasElement在 UI 布局更新完成时调用。
Rebuild(CanvasUpdate update)ICanvasElement当 Canvas 需要重建 UI 时调用(刷新布局和图形)。
OnInitializePotentialDrag(PointerEventData)IInitializePotentialDragHandler初始化拖拽状态,设置拖拽方向或行为。
OnDrag(PointerEventData)IDragHandler当用户拖动 Handle 时调用,更新滑动值。
OnMove(AxisEventData)IMoveHandler当使用键盘或手柄操作滑块时调用(如方向键)。
SetDirection(Direction, bool)Slider 自身设置滑动方向,并决定是否调整 Fill 和 Handle 的布局。
SetValueWithoutNotify(float)Slider 自身设置数值但不触发 onValueChanged 回调事件。
Protected Methods
方法名说明
OnDisable参照MonoBehaviour.OnDisable
Set设置Slider的值

Scrollbar

Scrollbar是一个用于滚动控制的UI组件,常与ScrollRect搭配使用,控制列表、文本区域、图片等内容的滚动

结构

Scrollbar = Rect Transform + Canvas Renderer + Image + Scrollbar
|___Sliding Area(滑动轨道范围)
           |___Handle(滑块) = Rect Transform + Canvas Renderer + Image

Scrollbar Panel

ScrollbarPanel

Scrollbar vs Slider

比较项ScrollbarSlider
用途滚动内容控制数值选择器
是否可设置 size
ScrollRect 结合常用较少
滑动方式滚轮、拖拽、点击轨道拖拽或编程控制

API

Properties
成员类型说明
handleRectRectTransform滑块(Handle)的 RectTransform。
directionScrollbar.Direction滑动方向(枚举)。
valuefloat当前滚动值,范围 [0, 1]。
sizefloat滑块在轨道中所占比例 [0, 1]。值越小,滑块越短。
numberOfStepsint分段数量。>1 时启用分段滚动。
onValueChangedUnityEvent<float>滚动值变化时调用。
Public Methods
方法名类型 / 接口说明
FindSelectableOnDown()Selectable(基类)返回下方可选的 UI 控件(用于键盘/手柄方向导航)。
FindSelectableOnLeft()Selectable(基类)返回左侧可选的 UI 控件。
FindSelectableOnRight()Selectable(基类)返回右侧可选的 UI 控件。
FindSelectableOnUp()Selectable(基类)返回上方可选的 UI 控件。
GraphicUpdateComplete()ICanvasElement在图形系统更新完成后调用,用于重绘完 UI 后的清理/处理。
LayoutComplete()ICanvasElement布局系统更新完成时调用,通常用于收尾处理。
OnBeginDrag(PointerEventData)IBeginDragHandler当开始拖动滑块时触发(鼠标按下并准备拖动)。
OnDrag(PointerEventData)IDragHandler拖动过程中持续触发,更新 value
OnInitializePotentialDrag(PointerEventData)IInitializePotentialDragHandler拖拽开始前初始化拖拽设置(如拖拽方向等)。
OnMove(AxisEventData)IMoveHandler响应键盘/手柄的移动事件(如方向键、左摇杆)。
OnPointerDown(PointerEventData)IPointerDownHandler当鼠标或触控按下滑条时触发。
OnPointerUp(PointerEventData)IPointerUpHandler当鼠标或触控释放时触发。
Rebuild(CanvasUpdate)ICanvasElement在 Canvas 需要重新构建 UI 时调用,如尺寸或内容更新。
SetDirection(Direction, bool)Scrollbar 本身设置滑动方向,并决定是否重新布置滑块布局。
SetValueWithoutNotify(float)Scrollbar 本身设置 value 但不触发 onValueChanged 回调,用于静默初始化。
Protected Methods
方法名所属说明
ClickRepeat(PointerEventData)协程函数(Coroutine)当按住滑条空白区域(非 Handle)时启动,用于模拟持续点击(滚动),直到释放。通常由 OnPointerDown 启动,用于实现“点住滚动”的行为。
OnDisable()MonoBehaviour 生命周期方法当组件或 GameObject 被禁用时调用。用于清理状态,比如停止滑动协程、取消事件等。

ClickRepeat工作原理

用户点击 Scrollbar 空白区域(非 Handle)
OnPointerDown 被触发
启动协程 ClickRepeat
每隔一段时间不断调整value,模拟“持续按压”
OnPointerUp 或 OnDisable 停止协程

ClickRepeat不会在拖动Handle时触发,仅当点击轨道空白部分时才会执行通常用于快速向上/向下滚动

Scroll View

结构

Scroll View = Rect Transform + Canvas Renderer + Image + Scroll Rect
|___Viewport = Rect Transform + Canvas Renderer + Image + Mask
|       |___Content
|___Scrollbar Horizontal
|       |___Sliding Area
|       |___Handle
|___Scrollbar Vertical
        |___Sliding Area
        |___Handle

Scroll Rect Panel

ScrollRectPanel

属性说明
Content滚动的内容区域(Transform)。必须设置。
Horizontal / Vertical是否允许横向 / 纵向滚动。
Movement Type滚动行为的类型:
Unrestricted(无限滚动)
Elastic(弹性回弹)
Clamped(限制在边界)
Elasticity弹性程度,适用于 Elastic 模式。
Inertia是否使用惯性滚动(拖动停止后缓慢减速)。
Deceleration Rate惯性减速速率(值越接近 0 减速越快)。
Scroll Sensitivity鼠标滚轮或拖动的灵敏度。
Viewport可视窗口(一般是带有 MaskRectMask2D 的 UI 元素)。
Horizontal/Vertical Scrollbar滚动条(可选)。
OnValueChanged滚动时触发的事件(Vector2,x 为横向偏移,y 为纵向偏移,范围 0~1)。

使用要点

1.Content必须配合Layout Group使用
常见组合:

2.可视区域需要加Mask
否则滚动时会“溢出显示”

3.Content的Pivot通常设为(0, 1)
也就是左上角,这样滚动方向更符合视觉直觉(从上往下滚)

API

Properties

内容控制

属性含义
content被滚动的内容区域,必须是 ScrollRect 的子节点,一般挂 Layout Group 和元素。
viewport可视区域,通常是带有 MaskRectMask2D 的 RectTransform,用于裁剪 content。

滚动方向控制

属性含义
horizontal是否启用 水平滚动
vertical是否启用 垂直滚动
horizontalNormalizedPosition当前水平滚动位置,0 = 左侧,1 = 右侧
verticalNormalizedPosition当前垂直滚动位置,0 = 底部,1 = 顶部
normalizedPosition一个 (x, y) 的向量,表示水平和垂直的标准化位置。

滚动行为与物理效果

属性含义
movementType滚动边界行为:
Unrestricted: 不限制内容滚动出界
Clamped: 限制内容不超出边界
Elastic: 允许超出边界但有弹性回弹
elasticity内容超出边界时的回弹强度(只适用于 Elastic 模式)。
inertia是否启用 惯性滚动(用户松手后内容继续滑动)。
decelerationRate惯性滚动时的减速率,越小减速越快,0~1。
velocity当前内容的滚动速度(仅运行时可读写)。

滚动灵敏度

属性含义
scrollSensitivity鼠标滚轮或触摸板的滚动灵敏度,值越大越灵敏。

滚动条相关

属性含义
horizontalScrollbar水平滚动条组件引用(可选)。
horizontalScrollbarSpacing水平滚动条与 viewport 之间的间距。
horizontalScrollbarVisibility滚动条的显示策略(自动、永久等)。
verticalScrollbar垂直滚动条组件引用(可选)。
verticalScrollbarSpacing垂直滚动条与 viewport 之间的间距。
verticalScrollbarVisibility垂直滚动条的显示策略。

事件

属性含义
onValueChanged滚动位置变化时的事件回调,参数是 Vector2(normalizedPosition)
可以用来联动其他 UI,或动态加载内容等。

与布局系统集成

这些属性主要是用于ScrollRect本身作为UI元素时的布局信息(一般不常改)

属性含义
minWidth / minHeight布局系统要求的最小宽高。
preferredWidth / preferredHeight建议的宽高,通常用于自动布局计算。
flexibleWidth / flexibleHeight是否可以在布局中灵活伸缩。
layoutPriority控制多布局系统下优先级(数字越高越优先)。
Public Methods

与布局系统有关的方法

这些方法一般由Unity的UI Layout系统自动调用,开发者很少直接使用,了解它们可以帮助搞清楚ScrollRect和布局系统的协作过程

方法说明
CalculateLayoutInputHorizontal()告诉布局系统如何计算内容的宽度需求。
CalculateLayoutInputVertical()告诉布局系统如何计算内容的高度需求。
SetLayoutHorizontal()设置子元素的水平布局(内部执行,如 Content 的定位)。
SetLayoutVertical()设置子元素的垂直布局。
LayoutComplete()布局系统完成后调用,通常用于布局结束时的清理。
Rebuild(CanvasUpdate update)在不同的 Canvas 更新阶段重建 UI(布局、绘制、交互等)。

拖拽相关方法(响应用户手势)

方法说明
OnBeginDrag(PointerEventData eventData)当用户开始拖动 ScrollRect 时触发(鼠标或触摸开始拖动)。初始化拖动参数。
OnDrag(PointerEventData eventData)拖动过程中持续触发,主要移动 Content
OnEndDrag(PointerEventData eventData)拖动结束时触发,决定是否开始 惯性滚动
OnInitializePotentialDrag(PointerEventData eventData)在系统检测到可能要开始拖拽时调用。设置拖拽相关参数,如 useDragThreshold
StopMovement()手动停止滚动(将 velocity 设为零),可用于外部中断滚动行为。

鼠标滚轮事件

方法说明
OnScroll(PointerEventData eventData)响应鼠标滚轮事件,常用于鼠标滑动滚动内容。ScrollRect 内部会根据 scrollSensitivity 来改变 content 的位置。

Canvas系统更新周期

方法说明
GraphicUpdateComplete()图形更新阶段完成后调用,通常用于清理绘制状态。
IsActive()ScrollRect 当前是否激活(继承自 UIBehaviour),用于判断是否参与渲染和交互。
示例

自定义拖动方向(只允许竖直)

public class VerticalOnlyScrollRect : ScrollRect
{
  public override void OnDrag(PointerEventData eventData)
  {
    if (!vertical) return;

    var delta = new Vector2(0, eventData.delta.y);
    base.OnDrag(new PointerEventData(eventData.eventSystem)
    {
      position = eventData.position,
      delta = delta
    });
  }
}

UI更新

Unity的UI系统在每一帧里,都按照一定顺序对所有UI元素做布局计算、绘制更新、交互处理,这个顺序被划分成了几个阶段

UI更新流程的3个阶段(CanvasUpdate)

Unity会调用实现了ICanvasElement接口的UI组件(如TextImageScrollRect等),按顺序执行:

阶段意义常见调用的方法
1.Layout 阶段计算大小、位置CalculateLayoutInputHorizontal/Vertical, SetLayoutHorizontal/Vertical
2.Graphic 阶段更新可视内容,比如文字、图片、颜色等GraphicUpdateComplete
3.LatePreRender 阶段最后准备渲染前的调整比如强制设置滚动位置等

TimeLine(Per Frame)

Update()
Layout阶段:
    - ScrollRect:计算内容区域位置
    - Text:计算文字排版
Graphic阶段:
    - Image:更新贴图
    - Text:更新文字网格
LatePreRender阶段:
    - ScrollRect:修正 normalizedPosition
渲染 → 显示画面

某些UI行为必须等到布局计算完成后才能准确执行,比如:

scrollRect.verticalNormalizedPosition = 0f;

如果放在Start()里,它可能在布局阶段之前就执行了,所以不会生效

正确的方式是:

Canvas.ForceUpdateCanvases(); // 强制执行Layout阶段
scrollRect.verticalNormalizedPosition = 0f;

UI Event System

UI Event System

Effects

UIEffectsPanel

Outline

Outline是UI元素(特别是Text或Image)边缘的描边效果,常用于:

可以使用Unity内置组件或者自定义Shader

方法原理
Unity 内置效果给文字/图片添加一个 UI 组件 Outline,复制顶点并偏移渲染多次
Shader 实现将 UI 元素边缘偏移若干方向采样贴图,合成边缘

内置Outline的原理:

Position As UV1

这是一个技术手段:将某个偏移后的顶点坐标值(如描边方向的位移)写入UV1通道,让Shader在片元阶段使用它来做偏移采样

用途:

Shadow

Shadow是给UI文本或图形加上的下投影阴影,常用于:

实现方式和Outline类似,也常用顶点偏移 + 颜色叠加实现;通常只需1此偏移绘制,不像Outline要多个方向

Layout System

详见Layout

Mask

详见Mask

UGUI渲染流程

UGUI的渲染是基于Canvas来驱动和管理的,Canvas是UGUI的核心渲染单元

UGUI组成核心

UGUI渲染总体流程

1.UI元素状态改变触发重建(Dirty)

2.Canvas重建

3.Canvas批处理

4.顶点提交

5.GPU渲染

示意图:

UI元素变化Dirty 
        
Canvas重建
        
顶点缓冲区重新生成OnPopulateMesh
        
批处理合并Batching
        
CanvasRenderer提交顶点
        
GPU渲染绘制

重要细节

UI性能优化

UI性能瓶颈来源

重点优化方向和方法

减少Canvas重绘范围

控制Draw Call数量

优化布局系统

文本优化

使用Pool技术复用UI元素

Unity UI Tookit

Unity UI Tookit是Unity推出的新一代UI框架,用于狗i按Editor UI(编译器工具)以及运行时UI(Runtime UI),逐渐称为UGUI的继任者。
它借鉴了Web的开发理念,使用类似HTML + CSS的语法(UXML + USS),结合C#逻辑代码

UI Toolkit组成

1.UXML(Unity XML)

<engine:VisualElement class="container">
  <engine:Label text="Hello UI Toolkit" class="title-label"/>
</engine:VisualElement>

2.USS(Unity Style Sheets)

.container {
  flex-direction: column;
  padding: 10px;
}

.title-label {
  font-size: 20px;
  color: white;
}

3.C#脚本

var root = GetComponent<UIDocument>().rootVisualElement;
var button = root.Q<Button>("myButton");
button.clicked += () => Debug.Log("Button clicked");

UI Tookit的优势

优点描述
数据驱动更好地支持 MVC/MVVM 等架构。
样式分离USS 类似 CSS,使样式和逻辑分离,维护性强。
高度自定义支持自定义控件、继承组件等。
原生支持编辑器工具创建自定义 Inspector、工具面板更加方便。
性能更好(Runtime UI)尤其在静态 UI 上比 UGUI 更高效。

UI Tookit vs UGUI

特性UI ToolkitUGUI
样式机制USS(类似 CSS)内联属性
布局方式FlexboxAnchors + RectTransform
可编程性更接近 Web 构建方式Unity 特有组件方式
编辑器支持完善,Inspector、EditorWindow需要自写代码
动态创建元素支持(动态加载 UXML)支持,但较繁琐
性能(静态 UI)更优中等
学习曲线偏陡峭(对 Web 不熟悉的人)更直观

使用场景

UI动画

Unity中做UI动画,有以下几种常见方式

Unity Animator Controller做UI动画

Tween动画库

利用UI CanvasGroup做渐隐渐显动画

使用代码插值做自定义动画

UI粒子动画和Shader动画

Timeline与UI动画