27.UGUI基础知识总结

  1. 27.总结
    1. 27.1 知识点
      1. 学习的主要内容
      2. 必须达到的水平
      3. 学会举一反三
      4. 一些和UI相关的知识
    2. 27.2 核心要点速览
      1. 发展脉络
      2. 为什么要专门学 UGUI
      3. 学法与内容主线
    3. 六大基础组件与编辑器入口
    4. Canvas画布组件
    5. CanvasScaler画布缩放器组件
    6. GraphicRaycaster 图形射线投射器
    7. EventSystem 组件
    8. Standalone Input Module 组件
    9. RectTransform矩形变换组件
    10. 三大基础控件
    11. Image图片控件
      1. Image 图片组件参数
      2. Image 图片代码控制
    12. Text
      1. Text 文本组件参数
      2. 富文本使用
      3. 边缘线和阴影
      4. Text 文本代码控制
    13. RawImage
      1. RawImage 原始图像组件参数
      2. RawImage 原始图像代码控制
    14. 组合控件共通
    15. Button按钮控件
    16. Toggle
      1. Toggle 开关组件参数
      2. Toggle 开关代码控制
      3. Toggle 监听事件的两种方式
    17. InputField
      1. InputField文本输入组件参数
      2. InputField监听事件的两种方式
    18. Slider
      1. Slider 滑动条组件参数
      2. Slider 监听事件的两种方式
    19. ScrollBar
      1. ScrollBar 滚动条组件参数
      2. ScrollBar 滚动条控件代码控制
      3. ScrollBar 监听事件的两种方式
    20. ScrollView滚动视图控件
      1. ScrollRect 滚动视图组件参数
      2. ScrollRect 滚动视图代码控制
      3. ScrollView 监听事件的两种方式
    21. Dropdown下拉列表控件
      1. DropDown 下拉列表组件参数
      2. DropDown 下拉列表代码控制
      3. DropDown 监听事件的两种方式
    22. 图集
    23. 进阶:事件、坐标与裁切
    24. UI事件监听接口
      1. UGUI 事件接口列表
        1. 常用事件接口
        2. 不常用事件接口
        3. 导航相关接口
      2. PointerEventData 指针目标数据类参数详解
    25. UI事件监听接口(EventTrigger)
      1. 使用事件触发器的方法
    26. 屏幕坐标转UI相对坐标
    27. Mask遮罩
    28. Mask遮罩模型、粒子特效显示在UI之前
    29. 异形按钮
    30. 自动布局组件
      1. 布局元素的布局属性
      2. 常见自动布局组件
        1. HorizontalVerticalLayoutGroup 水平垂直布局组件
        2. LayoutElement 布局元素组件
        3. GridLayoutGroup 网格布局组件
        4. ContentSizeFitter 内容大小适配器
        5. AspectRatioFitter 宽高比适配器
    31. CanvasGroup画布组
  2. 27.3 面试题精选
    1. 基础题
      1. 1. 六大基础组件挂在哪两个物体上
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      2. 2. Image 和 RawImage 资源类型差在哪
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      3. 3. Button 的 onClick 什么时候触发、怎么接代码
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      4. 4. UGUI 里打图集主要想解决什么问题
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      5. 5. 什么时候用事件接口而不是只绑 Button.onClick
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
    2. 进阶题
      1. 1. UIElements、UGUI、IMGUI 大致怎么分工
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      2. 2. GraphicRaycaster 的 Blocking 在 Overlay 下为何常显得没用
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      3. 3. Text 叠在按钮上点不透怎么排
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      4. 4. ScrollRect 里 Content 与滚动条引用要注意什么
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      5. 5. Sprite Packer 里 Legacy 模式和 Padding Power 是什么鬼
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      6. 6. ScreenPointToLocalPointInRectangle 四个参数怎么填
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
    3. 深度题
      1. 1. Scale With Screen Size 下三种 Screen Match Mode 怎么取舍
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      2. 2. Image 四种 Image Type 各解决什么界面需求
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      3. 3. InputField 的 onValueChanged 和 onEndEdit 何时触发
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      4. 4. 代码里怎么从 SpriteAtlas 取出一张子图
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章
      5. 5. CanvasGroup 三个开关各管什么、和子节点关系如何
        1. 题目
        2. 深入解析
        3. 答题示例
        4. 参考文章

27.总结


27.1 知识点

学习的主要内容

必须达到的水平

学会举一反三

一些和UI相关的知识


27.2 核心要点速览

发展脉络

阶段 要点
Unity 早期至 4.6 之前 官方主推 IMGUI 写界面;要做得漂亮、好用,很多项目会用第三方 NGUI
Unity 4.6 官方 UGUI 落地;业界从「第三方为主」开始明显转向官方方案。
Unity 5 一代 UGUI 功能和生态更成熟,逐渐成为商业项目里的默认选择之一。
Unity 2018 起 UIElements(现多称 UI Toolkit)强化,在编辑器侧很能打;与 UGUI 长期并存,分工不同。

为什么要专门学 UGUI

Unity 官方大致三条线:UIElementsUnity UI(UGUI)IMGUI。概述里用一张对标表记过典型分工(Editor 与运行时 game UI 不是同一块战场):

体系 运行时开发 UI 运行时游戏 UI Unity 编辑器
UIElements 视版本与项目而定 视版本与项目而定 主力方向之一
Unity UI,UGUI 常用 主力之一 不可用
IMGUI 多用于调试、工具向 不适合作为正式游戏 UI 的主力 常用

实务上:做游戏产品界面,UGUI 仍然是必须啃透的基本盘;和「只会写编辑器工具」用到的 UI 栈大概率不一样,面试里也经常被拿来对比。

学法与内容主线

  • 学法理论(组件与机制)+ 小题巩固 + 小实践串起来。
  • 内容线基础控件组合控件若干进阶专题用 UGUI 搭完整功能

六大基础组件与编辑器入口

  • 从哪创建:在 Hierarchy 里右键 UI,子菜单里从 Text、Image、Button 到 CanvasEvent System 都是 UGUI。场景里第一次需要根节点时,Unity 往往会自动补上 CanvasEventSystem
  • 编辑习惯:做布局时 Scene2D 视图、多用 Rect 工具(T) 改宽高和锚点,比在 3D 透视里硬挪 Transform 省心。

标准 UGUI 场景最少要分清两套对象:Canvas 根EventSystem。组件怎么分挂可以按下面记:

挂在哪 组件 角色
Canvas(及同一物体上) Canvas 决定渲染模式、排序等,是 UI 的「画布」
Canvas Scaler 分辨率变了 UI 怎么缩放,适配策略在这
Graphic Raycaster 参与 UI 图形射线检测,把指针事件落到具体 Graphic
RectTransform 所有可见 UI 节点都有;锚点、轴心、适配布局的核心
EventSystem Event System 管当前选中谁、事件往哪派发
Standalone Input Module 把鼠标键盘手柄输入翻译成 UI 事件(常见默认模块)

Canvas画布组件

内容 详情
Canvas 组件作用 用于创建和管理 UI,场景中可存在多个 Canvas 对象
渲染方式 - Screen Space - Overlay 覆盖模式,UI 始终显示在场景内容前方,会挡住场景模型。
参数:
- Pixel Perfect:是否开启无锯齿精确渲染(性能换效果)
- Sort Order:多个 Overlay Canvas 叠放时数值越大越晚绘制,显示越在上层
- Target Display:目标显示设备
- Additional Shader Channels:其他着色器通道,决定着色器可读取的数据
渲染方式 - Screen Space - Camera 摄像机模式,3D 物体可显示在 UI 之前。
参数:
- RenderCamera:用于渲染 UI 的摄像机,不推荐设为主摄像机,建议创建只渲染 UI 层的摄像机并关联,设置模式为仅深度,调整深度比主摄像机高,想让模型在 UI 前可创建为 UI 子物体
- Plane Distance:UI 平面在摄像机前方的距离,类似整体 Z 轴
- Sorting Layer:所在排序层
- Order in Layer:排序层的序号
渲染方式 - World Space 3D 模式,可将 UI 对象像 3D 物体一样处理,常用于 VR 或 AR。一般关联主摄像机,重置 UI 比例和长宽后,标准单位的 UI 图片大小和立方体一样。
参数:
- Event Camera:用于处理 UI 事件的摄像机,不设置则不能正常注册 UI 事件

CanvasScaler画布缩放器组件

组件作用:用于对Canvas中的UI元素进行适配,以适应不同的屏幕分辨率和设备。
三种适配模式:

  • 恒定像素模式(Constant Pixel Size):通过Scale Factor(缩放系数)和Reference Pixels Per Unit(单位参考像素)来全局缩放UI元素,单位参考像素与图片的Pixels Per Unit共同影响UI元素最终显示尺寸。
  • 缩放模式(Scale With Screen Size):最常用的模式,基于 Reference Resolution(参考分辨率)自适应。宽高比和参考不一致时靠 Screen Match ModeExpand(扩展模式,界面尽量完整可见,可能留黑边)、Shrink(尽量铺满视口,可能裁边)、Match Width Or Height(按滑杆偏向宽或高一边匹配,UI 相对「定尺」,仍可能黑边或裁切)。
  • 恒定物理模式(Constant Physical Size):涉及DPI(每英寸点数)、Physical Unit(物理单位)、Fallback Screen DPI(备用DPI)、Default Sprite DPI(默认图片DPI)等参数,与恒定像素模式的区别在于其基于物理单位和DPI来处理UI元素的显示。
  • 3D模式(World模式):有Dynamic Pixels Per Unit(UI中动态创建位图的单位像素数)和Reference Pixels Per Unit(单位参考像素,默认一个单位为100像素)等参数,用于处理3D场景中的UI相关设置。

GraphicRaycaster 图形射线投射器

主要作用:GraphicRaycaster 用于处理 UI 元素的射线检测,确定鼠标点击或触摸事件是否发生在 UI 元素上。

参数说明

参数 说明
Ignore Reversed Graphics 是否忽略反转图形。若勾选,当对象旋转了 x 轴或 y 轴时,点击该对象无效;若不勾选,点击始终有效。
Blocking Objects 射线被哪些类型的碰撞器阻挡,但在覆盖渲染模式下此设置无效。可选择能阻挡射线的碰撞器类型。
Blocking Mask 射线被哪些层级的碰撞器阻挡,同样在覆盖渲染模式下无效。需配合阻塞对象使用,只有对象处于勾选的层级,并且符合阻塞对象的类型,才能阻挡射线。

覆盖模式特性:在覆盖模式下,由于 UI 始终显示在最前面,Blocking Objects 和 Blocking Mask 参数无效。

EventSystem 组件

参数 说明
First Selected 可设置游戏开始时默认选中的游戏对象,关联对象后,运行游戏该对象会被默认选中。
Send Navigation Events 决定是否允许导航事件(如移动、按下、取消等)。勾选后,可通过 wasd 或上下左右键切换选择的对象。
Drag Threshold 定义了拖拽操作的阈值,即鼠标移动多少像素后会进入拖拽状态。

运行时在 EventSystem 组件自带的调试视图里能看到当前选中、射线打中的对象,查「点了没反应」时很实用。

Standalone Input Module 组件

参数 说明
Horizontal Axis 水平轴按钮对应的热键名,该名字需对应 Input 管理器中的设置。
Vertical Axis 垂直轴按钮对应的热键名,对应 Input 管理器中的设置。
Submit Button 提交(确定)按钮对应的热键名,对应 Input 管理器中的设置。
Cancel Button 取消按钮对应的热键名,对应 Input 管理器中的设置。
Input Actions Per Second 每秒允许键盘或控制器输入的数量。
Repeat Delay 按住按键时,连发开始前等待的秒数;与 Input Actions Per Second 搭配。
ForceModule Active 决定是否强制该模块处于激活状态。一般情况下,不会对该组件的参数进行修改。

RectTransform矩形变换组件

参数 说明
Pivot(轴心点) 取值范围为 0 - 1,以左下角为原点 (0, 0),右上角为 (1, 1)。
是旋转的中心点,与锚点共同用于位置计算。
影响宽高扩大或缩小时的伸缩方向。
Anchors(相对父矩形锚点) Min 是矩形锚点范围 X 和 Y 的最小值,Max 是最大值,取值范围 0 - 1。
当 Min 和 Max 对应的 xy 值完全贴合时,锚点以点的形式存在,根据锚点位置建立坐标系,结合轴心点计算 UI 对象位置。
当 Min 和 Max 对应的 xy 值分开时,根据锚点的四条边和 UI 对象的四条边计算位置,适用于背景图或需要子对象随父对象变化而变化的情况。
Pos(X, Y, Z) 轴心点(中心点)相对锚点的位置。
Width/Height 矩形的宽高。
Left/Top/Right/Bottom 矩形边缘相对于锚点的位置,当锚点分离时出现。
Rotation 围绕轴心点旋转的角度。
Scale 缩放大小。
Blueprint Mode(蓝图模式) 启用后,编辑旋转和缩放不会影响矩形,只会影响显示内容,一般不勾选。
Raw Edit Mode(原始编辑模式) 启用后,改变轴心和锚点值不会改变矩形位置,即改变轴心位置,图片显示位置改变,但 UI 对象的 Pos 位置数值不变。
不启用时,改变轴心位置,UI 对象的 Pos 位置也会改变。

三大基础控件

  • Image:吃 Sprite,是 UI 贴图、图标、按钮皮的主力;Image Type 管简单拉伸、九宫格、平铺、扇形/径向填充等表现。
  • RawImage:吃 Texture,大图全屏底、刻意不进图集的资源、运行时整张替换(含远端下载)都常见用它;UV Rect 在归一化坐标里裁一块区域显示。
  • Text(Legacy):字符串显示 + Rich Text 标签;描边、阴影要另挂 OutlineShadow 组件。三个都是 Graphic 后代,都有 Raycast Target,叠层时要注意谁挡住了点击。

Image图片控件

Image 图片组件参数

参数 说明
Source Image(源图形) 图片来源,图片类型必须是“精灵”类型。
Color(颜色) 图像的颜色,会在原图基础上叠加。
Material(材质) 图像的材质,一般使用 UI 的默认材质,不做修改。
Raycast Target(射线目标) 是否作为射线检测的目标,不勾选则不会响应射线检测,可穿透当前控件点击到后面的控件。
Maskable 是否能被遮罩,后续结合遮罩相关知识点讲解。
Image Type(图片类型) Simple(普通模式):均匀缩放整个图片。
Sliced(切片模式):9 宫格拉伸,只拉伸中央十字区域,需打开精灵编辑开启设置九宫格;Pixels Per Unit Multiplier 一般不修改;Fill Center 不勾选图片会中间空心。
Tiled(平铺模式):重复平铺中央部分。
Filled(填充模式):可用于做血条、cd 进度条等,有 Fill Method(填充方式)、Fill Origin(填充原点)、Fill Amount(填充量)、Clockwise(顺时针方向)等参数。
Use Sprite Mesh(使用精灵网格) 勾选后 Unity 会帮我们生成图片网格。
Preserve Aspect(保持长宽比) 缩放时保持图片宽高比,避免被拉变形。
Set Native Size(设置原生大小) 按当前 Sprite 的原始像素尺寸同步 RectTransform 宽高(与「铺满视口」无关)。

Image 图片代码控制

操作 代码示例 说明
获取 Image 组件 Image image = this.GetComponent<Image>(); 获取当前脚本所附加的 GameObject 上的 Image 组件。
设置显示图像 image.sprite = Resources.Load<Sprite>("ui_TY_fanhui_01"); 从资源文件夹中加载名为 “ui_TY_fanhui_01” 的 Sprite,并将其设置为 Image 的显示图像。
设置宽高 (transform as RectTransform).sizeDelta = new Vector2(200, 200); 将当前 GameObject 的 Transform 转换为 RectTransform,然后修改其尺寸为宽度 200、高度 200。
设置是否进行射线检测 image.raycastTarget = false; 禁用该 Image 组件的射线检测,使其不响应用户的点击事件。
设置颜色 image.color = Color.red; 将该 Image 组件的颜色设置为红色。

Text

Text 文本组件参数

参数 说明
Text(文本) 文本显示内容。
Font(字体) 文本所使用的字体。
FontStyle(字体样式) 包括 Normal(普通)、Bold(加粗)、Italic(斜体)、Bold And Italic(加粗 + 斜体)。
Font Size(字体大小) 文本字体的大小。
Line Spacing(行间距) 行之间的垂直间距。
Rich Text(富文本) 是否开启富文本功能。
Raycast Target 与 Image 相同,来自 Graphic;纯展示、不挡下面按钮时应关掉。
Alignment(对齐方式) 文本的对齐方式。
Align By Geometry(几何对齐) 使用字形集合形状范围进行水平对齐,而非字形指标,一般不勾选。
Horizontal Overflow(水平溢出) 处理文本太宽无法放入矩形范围的方式,有 Wrap(包裹模式,自动换行)和 Overflow(溢出模式,可溢出矩形框)。
Vertical Overflow(垂直溢出) 处理文本太高无法放入矩形范围的方式,有 Truncate(截断模式,超出部分裁剪)和 Overflow(溢出模式,可溢出矩形框)。
Best Fit(最佳适应) 忽略字体大小,自动调整使内容完全显示在矩形框中,可设置 MinSize(最小字体大小)和 MaxSize(最大字体大小)。

富文本使用

需开启富文本选项才能生效,示例如下:

  • 加粗:<b>文本内容</b>
  • 斜体:<i>文本内容</i>
  • 大小:<size=50>文本内容</size>
  • 颜色:<color=#ff0000ff>文本内容</color><color=red>文本内容</color>

边缘线和阴影

若要添加边缘线和阴影效果,需自行添加对应的组件,如 Outline(边缘线组件)和 Shadow(阴影组件)。

Text 文本代码控制

操作 代码示例 说明
获取 Text 组件 Text text = this.GetComponent<Text>(); 获取当前脚本所附加的 GameObject 上的 Text 组件。
设置文本显示内容 text.text = "哈哈哈哈哈"; 通过 text.text 变量设置文本显示内容。

RawImage

RawImage 原始图像组件参数

参数 说明
Texture(图像纹理) 可以拖拽任何类型的图进行关联。
UV Rect(UV 矩形) 表示图像在 UI 矩形内的偏移和大小。位置偏移 X 和 Y 取值范围是 0 - 1,大小偏移 W 和 H 取值范围也是 0 - 1。改变这些值,图像边缘会进行拉伸来填充 UV 矩形周围的空间,一般情况下不会改变此参数。

RawImage 原始图像代码控制

操作 代码示例 说明
获取 RawImage 组件 RawImage rawImage = this.GetComponent<RawImage>(); 获取当前脚本所附加的 GameObject 上的 RawImage 组件。
设置纹理 rawImage.texture = Resources.Load<Texture>("ui_TY_lvseshuzi_08"); 从资源文件夹中加载名为 “ui_TY_lvseshuzi_08” 的 Texture,并将其设置为 RawImage 组件的显示纹理。
设置 UV 矩形 rawImage.uvRect = new Rect(0, 0, 1, 1); 设置 RawImage 组件的纹理坐标矩形,创建一个左下角坐标为 (0, 0),宽度和高度都为 1 的 Rect 对象。

组合控件共通

  • Selectable 一族(Button、Toggle、Slider 等):多数带 InteractableTransition(None / ColorTint / Sprite Swap / Animation)、Navigation。禁用交互时勾掉 Interactable 即可统一灰显、不收输入。
  • 事件怎么接:点按一次 — Button.onClick;bool 状态 — Toggle.onValueChanged;连续数值 — Slider / **Scrollbar.onValueChanged(float)**;文本 — InputField.onValueChangedonEndEdit;下拉索引 — **Dropdown.onValueChanged(int)**。Inspector 多用 Dynamic 绑定才能把运行时参数传进方法。

Button按钮控件

  • 默认结构:父物体挂 Button + Image(可点底图),子物体可挂 Text 做字。改外观通常直接改这张 Image 的 Sprite / Color。
  • OnClick:在按钮区域内按下并抬起完成一次有效点击(中间滑出按钮区域会取消)。
要点 说明
Transition Color Tint / Sprite Swap / Animation 或用 None 省状态;Sprite Swap 下是 Selected Sprite 等图槽,不是颜色槽。
Navigation 配合 EventSystem 做方向键、Tab 切焦点;Explicit 可手工指定相邻控件。
代码 button.onClick.AddListener(...),成对 RemoveListener,清表用 RemoveAllListeners

Toggle

Toggle 开关组件参数

参数 说明
Interactable 决定是否接受输入。
Transition 响应用户输入的过渡效果。
Navigation 导航模式,设置 UI 元素在播放模式中控制器导航的方式。
IsOn 表示当前是否处于打开状态。
Toggle Transition 开关值变化时的过渡方式,有 None(无过渡,直接显示隐藏)和 Fade(淡入淡出)两种。
Graphic 用于表示选中状态的图片,默认关联创建 Toggle 时自动生成的勾形状选中图对象。
Group 关联的 ToggleGroup 单选框分组组件。创建一个空物体添加 ToggleGroup 组件作为管理组对象,将需管理的 Toggle 放在其下,并将每个 Toggle 的 Group 关联该 ToggleGroup 对象可实现单选框功能。Allow Switch Off 属性决定是否允许不选中任何一个单选框。
OnValueChanged 开关状态变化时执行的函数列表。

Toggle 开关代码控制

操作 代码示例 说明
获取 Toggle 组件 Toggle toggle = this.GetComponent<Toggle>(); 获取当前脚本所附加 GameObject 上的 Toggle 组件。
设置 Toggle 状态 toggle.isOn = true; 将 Toggle 状态设置为打开。
获取 ToggleGroup 组件 ToggleGroup toggleGroup = this.GetComponent<ToggleGroup>(); 获取当前脚本所附加 GameObject 上的 ToggleGroup 组件。
设置 ToggleGroup 属性 toggleGroup.allowSwitchOff = false; 禁止取消选中所有 Toggle。
获取 ToggleGroup 中选中的 Toggle foreach (Toggle item in toggleGroup.ActiveToggles()) { print(item.name + " " + item.isOn); } 遍历 ToggleGroup 中处于选中状态的 Toggle 并打印其名称和状态。

Toggle 监听事件的两种方式

拖脚本添加事件监听
在 Toggle 组件的 On Value Changed 列表里点加号,拖入对象并选带 bool 参数的公共方法,可挂多个回调。示例方法如下:

public void ChangeValue(bool isOn)
{
    print("状态改变" + isOn);
}

代码添加事件监听
使用 toggle.onValueChanged.AddListener 添加值改变事件监听。示例代码如下:

private void ChangeValue2(bool v)
{
    print("代码监听 状态改变" + v);
}

// 监听 toggle 的值改变事件,当值改变时调用 ChangeValue2 方法
toggle.onValueChanged.AddListener(ChangeValue2);

// 使用 lambda 表达式定义一个匿名方法并监听 toggle 的值改变事件
toggle.onValueChanged.AddListener((b) =>
{
    print("代码监听lambda表达式 状态改变" + b);
});

InputField

InputField文本输入组件参数

参数名称 描述
Interactable 是否接受输入
Transition 响应用户输入的过渡效果
Navigation 导航模式,设置UI元素在播放模式中控制器导航的方式
TextComponent 用于关联显示输入内容的文本组件
Text 输入框的起始默认值,也是当前文本输入的内容
Character Limit 可以输入字符长度的最大值
Content Type 输入的字符类型限制,包括Standard(标准模式)、Autocorrected(自动更正模式)、Integer Number(整数模式)、Decimal Number(十进制数模式)、Alphanumeric(字母数字模式)、Name(名字模式)、Email Address(邮箱地址模式)、Password(密码模式)、Pin(PIN 码模式)、Custom(自定义模式)等
Line Type 定义文本格式,有Single Line(单行显示)、Multi Line Submit(多行提交)、Multi Line NewLine(多行换行)三种模式
Placeholder 关联用于显示初始内容文本控件
Caret Blink Rate 光标闪烁速率
Caret Width 光标宽度
Custom Caret Color 自定义光标颜色
Selection Color 批量选中的背景颜色
Hide Mobile Input 隐藏移动设备屏幕上键盘,仅适用于iOS
Read Only 设置为只读,用户无法修改,输入无作用
OnValueChanged 内容改变时执行的函数列表
OnEndEdit 结束输入时执行的函数列表

InputField监听事件的两种方式

拖脚本监听事件
函数需有一个string类型的参数,选择动态的函数。对文本输入框的任何输入都会调用值改变时的事件,焦点不在文本输入框上就会调用结束编辑时的事件。示例代码如下:

public void ChangeInput(string str)
{
    print("改变的输入内容" + str);
}

public void EndInput(string str)
{
    print("结束输入时内容" + str);
}

代码添加监听事件
通过InputField.onValueChanged.AddListener添加值改变事件监听,InputField.onEndEdit.AddListener添加结束编辑事件监听。示例代码如下:

// 给inputField的onValueChanged事件添加监听器,当输入框文本内容改变时触发
inputField.onValueChanged.AddListener((str) =>
{
    print("代码监听 改变" + str);
});

// 给inputField的onEndEdit事件添加监听器,当输入框结束编辑时触发
inputField.onEndEdit.AddListener((str) =>
{
    print("代码监听 结束输入" + str);
});

Slider

Slider 滑动条组件参数

参数名称 描述
FillRect 关联的用于填充的进度条图形对象
Handle Rect 关联的用于滑动的滑动块图形对象
Direction 滑动条值增加的方向,包含:
- Left To Right:从左到右
- Right To Left:从右到左
- Bottom To Top:从下到上
- Top To Bottom:从上到下
Min Value 和 Max Value 最小值和最大值,滑动滚动条时值在最小到最大之间变化(左右、上下极值)
Whole Numbers 是否约束为整数值变化
Value 当前滑动条代表的数值
OnValueChanged 滑动条值改变时执行的函数列表

Slider 监听事件的两种方式

拖脚本监听事件
关联的函数要有一个 float 类型的参数,要选择动态的函数。若选择静态,值改变时会只打印右边输入框的值。示例函数如下:

public void ChangeValue(float v)
{
    print(v);
}

代码添加监听事件

slider.onValueChanged.AddListener(ChangeValue);
slider.onValueChanged.AddListener((v) => { print("代码添加的监听" + v); });

ScrollBar

ScrollBar 滚动条组件参数

参数名称 描述
Handle Rect 关联滚动块图形对象。
Direction 滑动条值增加的方向,包括:
Left To Right:从左到右
Right To Left:从右到左
Bottom To Top:从下到上
Top To Bottom:从上到下
Value 滚动条初始位置值,范围是 0 到 1。
Size 滚动块在条中的比例大小,范围是 0 到 1,为 1 时填满,代表不能拖动。
Number Of Steps 允许可以滚动的次数(不同滚动位置的数量),即可以一格一格变化时分成的格数。
OnValueChanged 滚动条值改变时执行的函数列表。

ScrollBar 滚动条控件代码控制

  1. 通过 GetComponent() 得到 Scrollbar 组件,如 Scrollbar scrollbar = this.GetComponent<Scrollbar>();
  2. 使用 Scrollbar.value 获取滚动条当前值,例如 print(scrollbar.value);
  3. 使用 Scrollbar.size 获取滚动条大小,例如 print(scrollbar.size);

ScrollBar 监听事件的两种方式

拖脚本监听事件
函数需要一个 float 参数,代表滚动条的值。示例代码如下:

public void ChangeValue(float v)
{
    print(v);
}

代码添加监听事件
通过 scrollbar.onValueChanged.AddListener 添加滑动条值变化的监听。示例代码如下:

// 注册监听滑动条值变化的事件,当滑动条的值发生变化时,执行下面的函数
scrollbar.onValueChanged.AddListener((v) => {
    print("代码监听的函数" + v);
});

ScrollView滚动视图控件

ScrollRect 滚动视图组件参数

参数名称 描述
Content 控制滚动视图显示内容的父对象,其尺寸决定滚动视图的拖动范围,默认关联 Viewport 的子对象 Content
Horizontal 启用水平滚动
Vertical 启用垂直滚动
Movement Type 滚动视图元素的运动类型,控制拖动时的反馈效果:
- Unrestricted:不受限制,随意拖动
- Elastic:回弹效果,滚出边缘后会弹回边界,Elasticity 为回弹系数,值越大回弹越慢
- Clamped:夹紧效果,始终限制在范围内,无回弹效果
Inertia 移动惯性,开启后松开鼠标有一定移动惯性
Deceleration Rate 减速率,范围 0 - 1,0 表示无惯性,1 表示不会停止
Scroll Sensitivity 滚轮和触摸板的滚动事件敏感性,增大值可加快滚轮滚动速度
Viewport 关联滚动视图内容视口对象,决定可视范围
Horizontal Scrollbar 关联水平滚动条
Visibility 设置滚动条的可视性模式:
- Permanent:一直显示滚动条
- Auto Hide:自动隐藏滚动条,不自动扩展视口范围
- Auto Hide And Expand Viewport:自动隐藏滚动条,并自动扩展内容 Viewport 视口范围
Spacing 滚动条和视口之间的间隔空间,控制间隙大小
OnValueChanged 滚动视图位置改变时执行的函数列表

删掉自带 Scrollbar 时,要在 ScrollRect 上把 Horizontal / Vertical Scrollbar 引用清空,并顺手把 Viewport、底图 Image 拉满,否则容易沿用「给滚动条留缝」的旧布局,留下空白或古怪间距。

ScrollRect 滚动视图代码控制

操作 代码示例 说明
获取 ScrollRect 组件 ScrollRect scrollRect = this.GetComponent<ScrollRect>(); 获取当前游戏对象上的 ScrollRect 组件
改变内容对象大小 scrollRect.content.sizeDelta = new Vector2(1000, 1000); 改变内容的大小,决定具体可拖动范围
设置滑动面板归一化位置 scrollRect.normalizedPosition = new Vector2(0, 1f); 重置 content 位置到左上,x 表示水平方向归一化值(0 - 1),y 表示垂直方向归一化值(0 - 1)

ScrollView 监听事件的两种方式

拖脚本监听事件

public void ChangeValue(Vector2 v)
{
    print(v);
}

代码添加监听事件

scrollRect.onValueChanged.AddListener((vec) =>
{
    print(vec);
});
参数名称 描述
Template 关联下拉列表对象
Caption Text 关联显示当前选择内容的文本组件
Caption Image 关联显示当前选择内容的图片组件,可能需手动创建 Image
Item Text 关联下拉列表选项用的文本控件
Item Image 关联下拉列表选项用的图片控件,可能需手动创建 Image
Value 当前所选选项的索引值
Alpha Fade Speed 下拉列表窗口淡入淡出的速度,越小显示越快
Options 存在的选项列表
OnValueChanged 下拉列表选项改变时执行的函数列表
操作 代码示例 说明
获取 DropDown 组件 Dropdown dropdown = GetComponent<Dropdown>(); 获取当前脚本所附加游戏对象上的 DropDown 组件
获取当前选中项索引 print(dropdown.value); 打印下拉菜单当前选中项的索引
获取当前选中项文本内容 print(dropdown.options[dropdown.value].text); 打印下拉菜单当前选中项的文本内容
添加新选项 dropdown.options.Add(new Dropdown.OptionData("123123123")); 在下拉菜单的选项列表末尾添加一个新选项

拖脚本监听事件
需要一个 Int 类型的参数,代表下拉列表的索引值。示例代码如下:

public void ChangeValue(int value)
{
    print(value);
}

代码添加监听事件

dropdown.onValueChanged.AddListener((index) =>
{
    print(index);
});

图集

  • 相对 NGUI 的习惯:NGUI 往往一上来就定图集;UGUI 可以先把界面搭顺,再集中打图集、收引用。
  • 为什么要打:多张小图若各自成材质/批次,容易把 DrawCall(DC) 顶高。DC 是 CPU 向 GPU 排队提交绘制 的密集程度指标,太高会占 CPU、表现为卡顿。把小图 打进少量大图,同屏 UI 更容易用 更少批次画完;口语里说「n 张碎图合成 1 张大图减 DC」是教学简化,实际批次还与 材质、Canvas 是否拆分等有关,但图集仍是 UI 性能课的常规手段。

Edit → Project Settings → Editor 中配置 Sprite Packer(条目名以当前 Unity 版本为准),模式可按下表理解:

设置模式 描述 是否在编辑模式下打包 是否在构建时打包 特殊选项
Disabled 不打图集;非 2D 工程常见默认
Enabled For Builds(Legacy Sprite Packer) 仅构建时打 Padding Power:缝大小按 2^n 像素量级
Always Enabled(Legacy Sprite Packer) 构建时打;编辑器里运行前也会打 是(运行前) 同上
Enabled For Build 仅构建时打(非 Legacy 文案)
Always Enabled 构建时打;编辑模式运行前也会打 是(运行前)
  • 打包勾选:原文建议 UGUI 图集勾选项里 关掉「允许旋转」「紧密包装」,减少算法排布上的意外。

代码加载(using UnityEngine.U2D):

SpriteAtlas spriteAtlas = Resources.Load<SpriteAtlas>("MyAtlas");
Sprite s = spriteAtlas.GetSprite("bk"); // 与图集中子 Sprite 名称一致,再赋给 Image.sprite 等

进阶:事件、坐标与裁切

  • 事件扩展:命名空间 UnityEngine.EventSystemsButton / Toggle 自带 UnityEvent 不够用时(长按、拖拽、双击、让纯 Image 吃指针),用 IPointerX / IDragX 等接口在脚本里实现回调;OnPointerEnter / Exit 在纯触摸环境往往弱于键鼠。
  • EventTrigger:把多路事件挂到 triggers 列表;每条 EventTrigger.Entry = **EventTriggerType + callback**,与手写多接口等价,Inspector 里拖 BaseEventData 方法常用 as PointerEventData 取坐标。
  • 屏幕 → UI 本地RectTransformUtility.ScreenPointToLocalPointInRectangle,父 RectTransform屏幕点负责渲染的 Cameraout 本地坐标拖拽里相机常用 eventData.pressEventCameraenterEventCamera,与当前 Canvas 模式一致。
  • Mask:父级 Mask 按自身图 Alpha 裁子树;被子 GraphicMaskableScrollViewViewport 常带遮罩裁滚动内容。
  • 3D / 粒子在 UI 前:非 Overlay 可掰 Z;或 专用相机 → RenderTexture → RawImage(与 Canvas 模式无关);粒子可用 Renderer 排序层压过 UI。
  • 异形点击:子 Image 拼可点区域(自下而上叠射线);或 alphaHitTestMinimumThresholdSprite 通常要开 Read/Write Enabled
  • 自动布局LayoutElement(Min / Preferred / Flexible)→ Horizontal & Vertical Layout GroupGrid Layout GroupContent Size FitterAspect Ratio Fitter
  • CanvasGroup:一把控制子树 AlphaInteractableBlocks RaycastsIgnore Parent Groups 可脱开上层 CanvasGroup 的叠加。

UI事件监听接口

UGUI 事件接口列表

常用事件接口
接口名 接口函数名 解释说明
IPointerEnterHandler OnPointerEnter 鼠标指针进入对象时调用
IPointerExitHandler OnPointerExit 鼠标指针退出对象时调用
IPointerDownHandler OnPointerDown 在对象上按下鼠标指针时调用
IPointerUpHandler OnPointerUp 松开鼠标指针时(在指针点击的对象上)调用
IPointerClickHandler OnPointerClick 在同一对象上按下再松开鼠标指针时调用
IBeginDragHandler OnBeginDrag 即将开始拖拽时在拖拽对象上调用
IDragHandler OnDrag 发生拖拽时在拖拽对象上调用
IEndDragHandler OnEndDrag 拖拽完成时在拖拽对象上调用
不常用事件接口
接口名 接口函数名 解释说明
IInitializePotentialDragHandler OnInitializePotentialDrag 找到拖动目标时调用,可用于初始化值
IDropHandler OnDrop 在拖动目标对象上调用
IScrollHandler OnScroll 鼠标滚轮滚动时调用
IUpdateSelectedHandler OnUpdateSelected 对象处于被选中状态时,每帧在选定对象上调用
ISelectHandler OnSelect 对象成为选定对象时调用
IDeselectHandler OnDeselect 取消选择选定对象时调用
导航相关接口
接口名 接口函数名 解释说明
IMoveHandler OnMove 发生移动事件(上、下、左、右等)时调用
ISubmitHandler OnSubmit 按下 Submit 按钮时调用
ICancelHandler OnCancel 按下 Cancel 按钮时调用

PointerEventData 指针目标数据类参数详解

PointerEventData 类继承自 BaseEventData 类,是 UGUI 事件系统中存储用户输入设备交互信息的重要参数,包含以下关键属性:

属性名 描述
pointerId 代表用户操作中不同按键的唯一标识,用于识别触发事件的按键
position 当前指针在屏幕坐标系中的实时位置,拖拽时持续更新
pressPosition 指针按下那一刻在屏幕上的初始位置
delta 从上一次事件到当前事件期间,指针在屏幕上的位移变化量
clickCount 连续点击的次数,用于区分单击和连击行为
clickTime 最后一次点击发生的时间戳,用于根据点击间隔执行不同逻辑
pressEventCamera 最后一次触发按下事件时所关联的摄像机实例
enterEventCamera 最后一次触发进入事件时所关联的摄像机实例

UI事件监听接口(EventTrigger)

使用事件触发器的方法

(1)拖曳脚本进行关联事件
关联的函数需要有一个 BaseEventData 参数。以下是示例代码:

public void TestPointerEnter(BaseEventData data)
{
    // 可以转换成子类 PointerEventData
    PointerEventData eventData = data as PointerEventData;
    print("鼠标进入 " + eventData.position);
}

通常的操作是将面板对象拖拽进来,然后选择面板脚本上的函数进行关联。

(2)代码添加

// 声明一个希望监听的事件对象 EventTrigger.Entry
// EventTrigger.Entry包含一个事件的类型ID eventID
// 和一个事件回调 callback
EventTrigger.Entry entry = new EventTrigger.Entry();

// 声明事件的类型为 PointerUp 指针抬起事件
entry.eventID = EventTriggerType.PointerUp;

// PointerUp 回调示例
entry.callback.AddListener((data) =>
{
    print("抬起");
});

// 把声明好的事件对象加入到 EventTrigger 当中叫triggers的entry列表中
eventTrigger.triggers.Add(entry);

屏幕坐标转UI相对坐标

RectTransformUtility类:是 RectTransform 的辅助类,主要用于坐标转换等操作。当前重要的函数是将屏幕空间上的点转换成 UI 本地坐标下的点。

坐标转换方法:RectTransformUtility.ScreenPointToLocalPointInRectangle 方法可将屏幕坐标点转换为父对象的本地坐标系中的点。该方法有四个参数:相对父对象、屏幕点坐标、摄像机、最终得到的点坐标。一般配合拖拽事件使用。

示例代码:

public class Lesson21_UGUI进阶_屏幕坐标转UI相对坐标 : MonoBehaviour, IDragHandler
{    
    public RectTransform parent; // 父对象

    public void OnDrag(PointerEventData eventData)
    {
        Vector2 nowPos; // 当前位置
        // 执行完这个函数后,会把屏幕坐标转换成 UI 本地坐标系下的值赋值给 nowPos
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            parent, // 相对父对象
            eventData.position, // 屏幕点坐标
            eventData.enterEventCamera, // 摄像机
            out nowPos); // 最终得到的点坐标

        this.transform.localPosition = nowPos; // 将当前对象的本地位置设置为转换后的坐标
    }
}

Mask遮罩

遮罩定义:遮罩是一种在不改变图片的情况下,让图片在游戏中只显示其中一部分的组件。ScrollView 滚动视图中的 ViewPort 就包含遮罩组件,使得滚动视图中只有在可见范围内才能看到组件。

遮罩使用方法:关键组件是 Mask 组件,在父对象上添加 Mask 组件即可遮罩其子对象。需要注意的是,想要被遮罩的 Image 需要勾选 Maskable;只要父对象添加了 Mask 组件,所有的 UI 子对象都会被遮罩;遮罩父对象图片不透明的地方显示,透明的地方被遮罩。

Mask遮罩模型、粒子特效显示在UI之前

  1. 直接用摄像机渲染 3D 物体:当 Canvas 的渲染模式不是覆盖模式(摄像机模式和世界(3D)模式)时,只要模型的 Z 轴在 UI 元素之前,模型就可以显示在 UI 之前。建议使用专门的摄像机渲染 UI 相关内容,UI 面板上的 3D 物体也用 UI 摄像机进行渲染。实现方法是设置一个专门渲染 UI 层的摄像机,让主摄像机不渲染 UI 层,UI 摄像机关联 Canvas,并将 Canvas 的渲染模式设置成摄像机模式,然后在 Canvas 上创建 Cube,调整缩放尺寸,层级设置为 UI 层,通过调整 Z 轴控制其显示位置。
  2. 将 3D 物体渲染在图片上,通过图片显示:专门使用一个摄像机渲染 3D 模型,将其渲染内容输出到 Render Texture 上,再将渲染的图显示在 UI 上。这种方式不受 Canvas 渲染模式的限制。实现步骤为创建一个模型层,创建一个专门渲染模型层的摄像机并改成纯色模式,创建一个立方体并设置为模型层,创建 RenderTexture 渲染器纹理并关联模型摄像机,在 Canvas 下创建 RawImage 并关联 RenderTexture 渲染器纹理。
  3. 粒子特效显示在 UI 之前:粒子特效的显示和 3D 物体类似。在摄像机模式下,可以在粒子组件的 Renderer 相关参数中改变排序层,让粒子特效始终显示在 UI 之前,不受 Z 轴影响。

异形按钮

异形按钮定义:形状不是传统矩形的按钮,例如只有独角兽区域能够被点击响应的按钮。

实现准确点击的方法:

  1. 添加子对象的形式:按钮根据图片矩形范围判断点击响应,范围判断自下而上,有子对象图片时,子对象图片范围也算可点击范围。可以用多个透明图拼凑不规则图形作为按钮子对象进行射线检测。
  2. 代码改变图片的透明度响应阈值Image.alphaHitTestMinimumThreshold,低于阈值的像素不参与射线命中;Sprite 资源通常需在 Import Settings 中开启 Read/Write Enabled 才会按像素 Alpha 做检测。

自动布局组件

布局元素的布局属性

要参与自动布局,布局元素必须包含布局属性,主要有以下 6 条:

属性名称 描述
Minimum width 该布局元素应具有的最小宽度
Minimum height 该布局元素应具有的最小高度
Preferred width 在分配额外可用宽度之前,此布局元素应具有的宽度
Preferred height 在分配额外可用高度之前,此布局元素应具有的高度
Flexible width 此布局元素应相对于其同级而填充的额外可用宽度的相对量
Flexible height 此布局元素应相对于其同级而填充的额外可用高度的相对量

布局时,布局元素大小设置遵循以下规则:

  1. 首先分配最小大小(Minimum width 和 Minimum height)。
  2. 若父容器有足够可用空间,则分配 Preferred width 和 Preferred height。
  3. 若上述分配完成后仍有额外空间,则分配 Flexible width 和 Flexible height。

一般情况下,布局元素的这些属性值为 0,但特定 UI 组件(如 Image 和 Text)依附对象的布局属性可能会改变。通常无需手动修改这些属性,若有需要,可手动添加 LayoutElement 组件进行修改。

常见自动布局组件

HorizontalVerticalLayoutGroup 水平垂直布局组件

即 Inspector 中的 Horizontal Layout GroupVertical Layout Group,将子对象横排或纵排;组件挂在父物体,子物体被布局。其参数如下:

参数名称 描述
Padding 左右上下边缘的偏移位置
Spacing 子对象之间的间距
ChildAlignment 九宫格对齐方式
Control Child Size 是否控制子对象的宽高
Use Child Scale 在设置子对象大小和布局时,是否考虑子对象的缩放
Child Force Expand 是否强制子对象扩展以填充额外可用空间
LayoutElement 布局元素组件

可给子对象添加该组件,例如设置布局属性最小宽和最小高为 100,即便父对象很小,子对象最小也会保持宽高 100。

GridLayoutGroup 网格布局组件

可将子对象当成格子,并设置它们的大小和位置,一般在滚动容器添加到 content 上,和 ContentSizeFitter 内容大小适配器一起使用。其参数如下:

参数名称 描述
Padding 左右上下边缘的偏移位置
Cell Size 每个格子的大小
Spacing 格子之间的间隔
Start Corner 第一个元素所在的位置(四个角)
Start Axis 沿着哪个轴放置元素,Horizontal 水平放置并换行,Vertical 竖直放置并换列
Child Alignment 格子的对齐方式(九宫格)
Constraint 行列约束,有 Flexible(灵活模式,根据容器大小自动适应)、Fixed Column Count(固定列数)、Fixed Row Count(固定行数)三种模式
ContentSizeFitter 内容大小适配器

可自动调整 RectTransform 的宽度和高度,使组件自动设置大小,常用于 Text 组件,或与其他布局组件一起使用。其参数如下:

参数名称 描述
Horizontal Fit 控制宽度的方式
Vertical Fit 控制高度的方式

可选参数包括:

  • Unconstrained:不根据布局元素伸展宽度或高度。
  • Min Size:根据布局元素的最小宽度或高度伸展。
  • Preferred Size:根据布局元素的首选宽度或高度伸展宽度。

若滚动视图中的元素动态添加,滚动视图不会自动改变大小,可给滚动视图添加自动布局组件和内容大小适配器组件,使其动态添加时自动更改宽高。

AspectRatioFitter 宽高比适配器

可让布局元素按一定比例调整自身大小,并在父对象内部根据父对象大小进行适配。其参数如下:

参数名称 描述
Aspect Mode 适配模式,用于调整矩形大小以实现宽高比
Aspect Ratio 宽度除以高度的比值,即宽高比

Aspect Mode 的可选值及含义:

  • None:不对矩形进行宽高比适配。
  • Width Controls Height:根据宽度自动调整高度。
  • Height Controls Width:根据高度自动调整宽度。
  • Fit In Parent:自动调整宽度、高度、位置和锚点,使矩形适应父项的矩形,同时保持宽高比,可能会出现“黑边”。
  • Envelope Parent:自动调整宽度、高度、位置和锚点,使矩形覆盖父项的整个区域,同时保持宽高比,可能会出现“裁剪”。

CanvasGroup画布组

参数名称 描述
Alpha 用于整体控制面板的透明度,通过调整该值可实现面板的淡入淡出效果
Interactable 控制面板整体的启用和禁用状态。设置为 true 时,面板及其子对象可与用户交互;设置为 false 时,面板及其子对象无法与用户交互
Blocks Raycasts 用于设置面板是否阻挡射线检测。设置为 true 时,面板会阻挡射线;设置为 false 时,射线可穿过面板
Ignore Parent Groups 勾选后,该物体子树在计算 Alpha / Interactable / Blocks Raycasts不再吃父级 CanvasGroup 的成组效果;用于嵌套面板要单独淡入淡出或与父层点击穿透策略解耦时

27.3 面试题精选

基础题

1. 六大基础组件挂在哪两个物体上

题目

UGUI 常说的「六大基础组件」分别是什么?一般各自挂在场景的哪两个节点上?

深入解析
  • Canvas 物体上四个CanvasCanvas ScalerGraphic Raycaster,再加和 Transform 一体的 RectTransform(所有 UI 节点都有)。
  • EventSystem 物体上两个Event SystemStandalone Input Module。输入经 EventSystem 分发,GraphicRaycaster 侧才把点按到具体 Image、Button 上。
  • 记法:一半管「画出来和怎么适配、怎么射线检测」,一半管「谁收到了输入」。
答题示例

Canvas 上有 Canvas、Canvas Scaler、Graphic Raycaster,再加 RectTransform。

EventSystem 上有 Event System 和 Standalone Input Module,负责点击和导航事件。

参考文章
  • 2.UGUI基础-六大基础组件-概述

2. Image 和 RawImage 资源类型差在哪

题目

UGUI 里 ImageRawImage 分别接什么类型的资源?各举一个更合适的用法。

深入解析
  • ImageSource Image 必须是 Sprite,和图集、九宫格切片、Image Type 那一套深度绑定,适合做图标、按钮、血条底图等高频 UI 元素。
  • RawImageTexture 可以是任意 Texture(含 Texture2D 等),不强求先进 Atlas;全屏背景、刻意不打图集的大图、网络拉下来的整张纹理更省心。
  • 答到「Sprite vs Texture」「谁更贴 UI 工作流、谁更贴纯贴图/大图」就及格。
答题示例

Image 用 Sprite,做 UI 切片、按钮图;RawImage 用 Texture,大图底图或不进图集的资源。

要和 Image Type、图集打配合就用 Image;只要整张往屏上糊或经常换一张 Texture 就用 RawImage。

参考文章
  • 8.UGUI基础-三大基础控件-Image图片控件
  • 10.UGUI基础-三大基础控件-RawImage原始图像控件

3. Button 的 onClick 什么时候触发、怎么接代码

题目

UGUI ButtonOn Click 大概在什么时机触发?Inspector 挂方法和 onClick.AddListener 各要注意什么?

深入解析
  • 时机:指针在按钮可交互区域内完成一次按下再抬起,且未因移出区域等原因取消,UnityEvent 才派发;不是 OnPointerDown 单次。
  • Inspector:可挂多个回调;需把运行时参数传给方法时选 Dynamic,避免「静态绑定只带固定值」的坑。
  • 代码AddListener 注册,RemoveListener 按委托移除,RemoveAllListeners 清空;销毁按钮前若曾用匿名 lambda 注册,要记得配对清理,否则偶有悬挂引用(具体看项目生命周期)。
答题示例

在按钮上完整点完一次,抬起时触发 onClick。

Inspector 用 Dynamic 才能把滑条值等传进方法;代码里 AddListener,不用了 Remove。

参考文章
  • 11.UGUI基础-组合控件-Button按钮控件

4. UGUI 里打图集主要想解决什么问题

题目

做 UGUI 时为什么要打图集?和 DrawCall(DC)之间怎么口头解释清楚?

深入解析
  • 目的:把很多张小 Sprite 合并进少量大纹理,让一整块界面更可能 一次批次、少次提交画出来,减轻 CPU 侧排队、切换材质的开销。
  • DC 口径:DC 常说成 CPU 通知 GPU 再来一笔绘制 的次数;碎图多、材质分裂,就容易把次数顶上去,表现为帧时间尖刺或掉帧。
  • 边界:口语「n 张变 1 张就 1 个 DC」是教学简化;真机还要看 Canvas 是否切开、是否同一材质/同一图集引用 等。
答题示例

打图集是为了让一批 UI 少几次绘制提交,CPU 少忙活。

DC 太高会卡;图集把碎图合成大图是常规优化手段,但实际批次还看 Canvas 和材质。

参考文章
  • 18.UGUI基础-图集制作

5. 什么时候用事件接口而不是只绑 Button.onClick

题目

已有 Button 时会用 On Click。那在什么需求下你会改用 IPointerDownHandler / IDragHandler 一类接口,或挂 EventTrigger

深入解析
  • UnityEvent 能兜住的:标准单击、Slider/Toggle 自带值变化等,先用组件自带列表最省事。
  • 接口 / Trigger 上场:要 按下时长、拖拽轨迹、双击、滚轮、滚动区内精细指针逻辑,或 Image / RawImage 没有现成 OnClick 却要响应指针;接口在 同一脚本里写清状态机,EventTrigger 则适合 Inspector 配表 或与 面板脚本集中登记。
  • 代价:脚本要挂在接收射线的对象上且一般要开 Raycast Target;触摸机上 Enter/Exit 的行为别当键鼠完全等价。
答题示例

标准点击用 Button;长按、拖、让纯图响应指针,用接口或 EventTrigger。

EventTrigger 就是少写几个接口文件、把 Entry 往列表里塞。

参考文章
  • 19.UGUI进阶-UI事件监听接口
  • 20.UGUI进阶-EventTrigger事件触发器

进阶题

1. UIElements、UGUI、IMGUI 大致怎么分工

题目

Unity 里经常听到 UIElements(UI Toolkit)、Unity UI(UGUI)、IMGUI 三套东西,从「做商业游戏界面」和「写编辑器工具」两个角度,你会怎么区分它们?

深入解析
  • 叫法:官名 Unity UI,口语 UGUI 即同一套;主要面向运行时玩家点得到的游戏界面,不是做 Editor 窗口的主力。
  • UGUI运行时游戏 UI 的事实标准之一,Inspector 里拖组件、场景里摆层次,和相机、Canvas、EventSystem 一整套走。
  • IMGUI:偏即时模式,在 Editor 里写工具、在运行时用 OnGUI 做调试或极简界面还行;正式游戏 UI一般不用它扛大旗。
  • UIElements / UI Toolkit:Unity 中后期强推的保留模式 UI,编辑器侧大量新功能用它;运行时是否采用要看团队版本与项目选型,和 UGUI 是并存关系,不是「学了 A 就不用 B」的简单替换。

回答时抓住:谁是给玩家点的游戏界面主力谁是给策划程序在编辑器里用的谁是历史包袱和调试向,就够使面试官听出你是在项目里做过事的。

答题示例

官名 Unity UI,口头说 UGUI;玩家点得到的游戏界面主力还是这套。

IMGUI 多为编辑器工具或调试;UI Toolkit 在编辑器侧越来越重要,和 UGUI 并行,选型看项目。

参考文章
  • 1.概述

2. GraphicRaycaster 的 Blocking 在 Overlay 下为何常显得没用

题目

GraphicRaycaster 里有 Blocking Objects、Blocking Mask,为什么说在 Screen Space - Overlay 下它们基本不起作用?

深入解析
  • Overlay 下整个 UI 画在屏幕最前,和场景里 3D 碰撞器的空间关系脱钩;教程里给的原话是:UI 永远在最前时,用 3D 碰撞器去「挡 UI 射线」这条链路不成立,所以 Blocking 相关项在覆盖模式下无效。
  • 到了 Screen Space - Camera 或需要让 3D 与 UI 在同一套深度里算前前后后时,Blocking 才有设计意义。
  • 面试加分:能顺带提到「真正要点还是要先搞清楚当前 Canvas 渲染模式」。
答题示例

Overlay 时 UI 直接盖在最上层,不按世界空间去和碰撞体挡射线,所以 Blocking 设了也白设。

Camera 模式才可能让 3D 挡在 UI 前之类的情况需要再看 Blocking;模式不对就别瞎调碰撞体掩码。

参考文章
  • 5.UGUI基础-六大基础组件-GraphicRaycaster图形射线投射器组件

3. Text 叠在按钮上点不透怎么排

题目

界面上 Text 盖在 Button 上面,运行时发现点按钮没反应,很常见的原因之一是什么?怎么改?

深入解析
  • Text 继承 Graphic,默认 Raycast Target 打开,射线会在文字区域被「截胡」,后面的 Button 收不到点击。
  • 处理:关掉 Text 的 Raycast Target,或把文字做成 Button 子节点由 Button 统一接射线、或调整层级让可点区域不被纯展示 Text 挡住。
  • 进阶可提:同类的 Image 纯底图也要养成「不交互就关 Raycast」的习惯,少一层误挡点击。
答题示例

Text 默认参与射线检测,把射线挡在字上就点不到下面按钮。

展示用文案把 Raycast Target 关掉,或者结构调整让 Button 吃到事件。

参考文章
  • 9.UGUI基础-三大基础控件-Text文本控件

4. ScrollRect 里 Content 与滚动条引用要注意什么

题目

ScrollRect 的可滚范围主要由谁决定?若删掉预设的水平或垂直 Scrollbar,除了拆对象还要在组件上做什么?

深入解析
  • ContentRectTransform 尺寸相对 Viewport 越大,能拖动的余量越多;Content 小于等于视口时本来也滚不动多少,配合 Visibility 可自动藏条。
  • 原文点名:删掉滚动条后必须在 ScrollRect 把对应滚动条字段置空,否则易出异常或隐性问题;布局上把 Viewport铺满,避免还为滚动条留了缝。
  • normalizedPosition (0,1) 一类可代码归位到边角,做背包重置列表时常用。
答题示例

能滚多远看 Content 比 Viewport 大多少。

删 Scrollbar 要在 ScrollRect 上空引用,viewport 拉满别留缝。

参考文章
  • 16.UGUI基础-组合控件-ScrollView滚动视图控件

5. Sprite Packer 里 Legacy 模式和 Padding Power 是什么鬼

题目

Edit → Project Settings → Editor 里老版 Legacy Sprite Packer 和新的打包开关主要差在哪?Padding Power 数字大致怎么理解?

深入解析
  • Legacy 行:多一个 Padding Power,管打包时 精灵之间、精灵与图集边 留多大缝,取值为 2 的 n 次方 像素量级,用来给过滤、采样留余量,减裂边和穿帮。
  • Always Enabled 相对 Enabled For Builds:多了编辑模式下跑游戏前也会打,本地调 UI 时更容易和真机构建表现一致;只开 For Builds 则编辑器里未必先帮你打齐。
  • 版本句:菜单名、是否 Legacy 以当前 Unity 文档为准;面试答「Legacy 多 padding、Always 会在进 Play 前打」即可。
答题示例

Legacy 多套一个 Padding Power,缝按 2 的幂来。

Always Enabled 编辑器运行前也会打包;只 For Builds 就偏上包体阶段。

参考文章
  • 18.UGUI基础-图集制作

6. ScreenPointToLocalPointInRectangle 四个参数怎么填

题目

RectTransformUtility.ScreenPointToLocalPointInRectangle 的四个参数各是什么?拖拽里为什么常从 PointerEventData 里取摄像机?

深入解析
  • rect:作为「本地空间原点」的那个 RectTransform,一般是拖动对象的父级或容器底。
  • screenPoint:屏幕像素坐标,拖拽里直接用 eventData.position
  • cam:参与这次 UI 射线/绘制的 CameraScreen Space - Camera 下必须对上渲染该 Canvas 的那台相机,否则点会飘;常用 eventData.pressEventCameraenterEventCamera
  • localPointout 到的 父 rect 本地 坐标,再赋给 anchoredPositionlocalPosition 视锚点习惯而定。
  • 比手写 position += delta 更稳,因为统一走 RectTransform 数学。
答题示例

父 Rect、屏幕点、相机、out 本地点。

相机要从事件数据拿,和画 UI 的那台一致,不然坐标对不上。

参考文章
  • 21.UGUI进阶-屏幕坐标转UI相对坐标

深度题

1. Scale With Screen Size 下三种 Screen Match Mode 怎么取舍

题目

CanvasScaler 选 Scale With Screen Size 后,ExpandShrinkMatch Width Or Height 大致各会带来什么画面结果?项目里怎么选?

深入解析
  • Expand:缩放后整套 UI 仍完全落在安全区内,宁可上下左右留 黑边,适合「一条边也不能少」的界面稿。
  • Shrink尽量放大去贴满视口,宁可 裁掉 一部分边缘内容,适合强调铺满、可接受少量出框。
  • Match Width Or Height:在参考分辨率与实机比例不一致时,偏向按宽度或按高度去算缩放,中间再辅以裁切或黑边,UI 元素相对尺寸更「钉死」,手游横竖屏要微调时常见用滑杆去靠宽或靠高。
  • 没有万能默认值:听美术和策划要「必须全看见」还是「必须撑满」,再反推选 Expand 还是 Shrink;要兼顾多种长宽比再动 Match。
答题示例

Expand 宁可黑边也要整张 UI 露完;Shrink 宁可裁边也要铺满。

Match 是偏宽还是偏高去算缩放,横竖屏分歧大时常用。跟策美对齐是要裁还是要边再说。

参考文章
  • 4.UGUI基础-六大基础组件-CanvasScaler画布缩放器组件

2. Image 四种 Image Type 各解决什么界面需求

题目

Simple / Sliced / Tiled / Filled 四种 Image Type 分别适合什么效果?Sliced 要额外在资源侧做什么?

深入解析
  • Simple:整张贴图按比例缩放,适合形状简单、不需要九宫保护的图标。
  • Sliced:九宫格,只拉中间、四角不穿帮;必须在 Sprite Editor 里设好 Border,否则和 Simple 拉糊没区别。
  • Tiled:中间区域重复平铺,适合做底纹类填充。
  • Filled:用 Fill Amount 控制可见比例,配合 Fill MethodFill OriginClockwise 做血条、CD 圆环等进度表现。
答题示例

Simple 整图缩放;Sliced 九宫格要在 Sprite 上切边;Tiled 平铺;Filled 做进度裁剪。

Sliced 不开 border 九宫格就不生效。

参考文章
  • 8.UGUI基础-三大基础控件-Image图片控件

3. InputField 的 onValueChanged 和 onEndEdit 何时触发

题目

InputFieldonValueChangedonEndEdit 分别在什么时机回调?做「实时搜索」和「提交再校验」各该听哪个?

深入解析
  • onValueChanged(string):字符串每变一次就触发,包括逐字输入、删字、代码改 text,适合即时预览、字数提示、客户端过滤。
  • onEndEdit(string):输入域失焦或完成一次提交(如按回车)时触发,适合整串校验、发请求、写存档,避免每个字符都请求。
  • Inspector 绑方法需 string 参数并选 Dynamic;与 Content TypeCharacter Limit 组合决定能输入什么。
答题示例

值一变就 onValueChanged;点别处或回车那种结束输入走 onEndEdit。

联想、实时提示走前者,确定再提交走后。

参考文章
  • 13.UGUI基础-组合控件-InputField文本输入控件

4. 代码里怎么从 SpriteAtlas 取出一张子图

题目

运行时用代码加载 SpriteAtlas 并取其中一张 Sprite,要引哪个命名空间?GetSprite 传的字符串该和谁对齐?

深入解析
  • 命名空间UnityEngine.U2D,类型是 SpriteAtlas
  • 加载:示例用 Resources.Load<SpriteAtlas>("MyAtlas"),路径与 Resources 下相对路径一致(不带扩展名);实际项目常改 Addressables / AssetBundle,思路仍是先拿 Atlas 再 GetSprite
  • 名字GetSprite("bk") 里必须是图集中该 Sprite 的名称(与导入后 Sprite 名一致),否则取空或抛错;取出后可赋给 Image.sprite
答题示例

引用 UnityEngine.U2D,Load 出 SpriteAtlas 再 GetSprite。

字符串要和图集里的 Sprite 名一模一样,才能对上那张小图。

参考文章
  • 18.UGUI基础-图集制作

5. CanvasGroup 三个开关各管什么、和子节点关系如何

题目

CanvasGroupAlphaInteractableBlocks Raycasts 分别影响什么?Ignore Parent Groups 什么时候要勾?

深入解析
  • Alpha:整棵子树 Graphic 的显式透明度乘子,做面板淡入淡出常用。
  • Interactable:关掉后相当于整面板 不可交互,子控件收不到输入(与单独关每个 Selectable 相比是一把梭)。
  • Blocks Raycasts:关掉后射线穿过该组,后面 UI 能接到点击;开则按层级正常挡。
  • Ignore Parent Groups:勾选后本物体子树不再叠加父级 CanvasGroup 对 Alpha、可交互、挡射线的成组结果;嵌套弹窗要单独渐隐或与父层穿透策略分开时使用(层多时要和策划对齐)。
答题示例

Alpha 管显隐渐变;Interactable 管整组能不能点;Blocks Raycasts 管挡不挡射线。

Ignore Parent Groups 用来脱离父级 CanvasGroup 对这一套的成组影响。

参考文章
  • 26.UGUI进阶-CanvasGroup画布组


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏