【Unity基础详解】(9)Unity核心:UI系统
三万字+各个实用案例,彻底讲清楚Unity的UI系统,重点在UGUI的使用。IMGUI采用无状态代码驱动方式,适合编辑器扩展开发、调试工具和原型设计,通过OnGUI()实时绘制界面元素。UGUI是Unity主流UI解决方案,基于Canvas+UI控件+EventSystem结构,支持灵活布局和交互,适用于游戏HUD、菜单等场景。两套系统各具特点,IMGUI适合程序员快速开发工具,UGUI则更适合复
目录
2.2.2.2 Standalone Input Module 组件
1 GUI
1.1 GUI简介
IMGUI(Immediate Mode GUI)是一种基于代码的即时模式 GUI 系统,与 Unity 基于游戏对象的 UI 系统不同。这套系统专为程序员设计,采用代码驱动的工作方式。开发者需在 OnGUI() 方法中实时编写界面绘制和交互逻辑代码,每帧都需要重新声明 UI 元素。由于系统缺少内置的布局和样式管理功能,开发者需要自行维护所有 UI 元素的状态。
1.2 核心特点
无状态:UI 元素没有持久化的对象表示,每一帧都会根据当前状态重新绘制。
代码驱动:所有 UI 都通过代码动态创建,例如使用GUI.Button(new Rect(10, 10, 50, 20), "Click"); 这类调用。
执行顺序:OnGUI() 方法每帧可能被多次调用,用于处理不同的布局和事件。
1.3 主要用途
编辑器扩展开发:创建自定义的 Inspector、EditorWindow 和工具窗口是 IMGUI 最常用且最擅长的应用场景。
游戏调试工具:可用于快速绘制游戏中的调试信息,构建测试按钮和控制面板。
原型开发:特别适合在项目初期快速搭建简单 UI 界面进行功能验证。
注意事项:
OnGUI 每帧执行,是专门用于 GUI 界面绘制的函数;
建议仅在其中执行 GUI 相关的界面绘制和操作逻辑;
执行顺序位于 OnDisable 之前,LateUpdate 之后;
所有继承自 MonoBehaviour 的脚本都可以通过 OnGUI 方法绘制 GUI 界面。
1.4 文本和按钮控件
private int clickCount = 0;
private string textField = "Hello IMGUI";
private void OnGUI()
{
// 1. 创建一个标签 (Label)
GUI.Label(new Rect(10, 10, 200, 20), "This is a basic lable");
// 2. 创建一个按钮 (Button)
// GUI.Button 方法会返回一个布尔值,当该按钮在本帧被点击时为 true
if (GUI.Button(new Rect(10, 40, 150, 30), "Click Count:" + clickCount))
{
// 当按钮被点击时,增加计数
clickCount++;
Debug.Log("Button Click! Count:" + clickCount);
}
// 3. 创建一个文本框 (TextField)
// 将用户在文本框输入的内容返回并存储回 textField 变量
textField = GUI.TextField(new Rect(10, 80, 1500, 30), textField);
}
代码说明:
- new Rect(x, y, width, height)定义了 UI 控件在屏幕上的位置和大小(以像素为单位)。(0, 0)是屏幕左上角。
- GUI.Button()返回bool,只有在点击发生的这一帧才会返回true。
- GUI.TextField()返回string,即用户输入的内容。你必须将返回值赋回给原始变量(如textField)才能更新它,这正是“无状态”的体现。

1.5 GUI Layout
private float sliderValue = 50f;
private bool toggleState = false;
private int toolbarIndex = 0;
private string[] toolbarLabels = { "Tab 1", "Tab 2", "Tab 3" };
private void OnGUI()
{
// 开始一个自动垂直排列的区域
GUILayout.BeginVertical(GUILayout.Width(200));
// 1. 工具栏 (Toolbar)
toolbarIndex = GUILayout.Toolbar(toolbarIndex, toolbarLabels);
// 2. 根据选中的工具栏标签显示不同的内容
switch (toolbarIndex)
{
case 0:
GUILayout.Label("You are on Tab 1");
break;
case 1:
GUILayout.Label("Welcome to Tab 2");
break;
case 2:
GUILayout.Label("This is Tab 3");
break;
}
// 3. 滑动条 (Slider)
// 我们需要一个标签来显示当前值
GUILayout.Label("Slider Value:" + sliderValue.ToString("F0"));
sliderValue = GUILayout.HorizontalSlider(sliderValue, 0f, 100f);
// 4. 开关 (Toggle)
toggleState = GUILayout.Toggle(toggleState, "This is a Toggle");
if (toggleState)
{
GUILayout.Label("The Toggle is ON");
}
// 5. 一个大的按钮
if(GUILayout.Button("A Large Layout Butoon", GUILayout.Height(50)))
{
Debug.Log("Layout Button Pressed! Slider is :" + sliderValue);
}
// 结束垂直区域
GUILayout.EndVertical();
}
代码说明:
- GUILayout.BeginVertical()/GUILayout.EndVertical()定义了一个区域,其中的控件会自动垂直排列。类似的还有BeginHorizontal/EndHorizontal。
- GUILayout是 IMGUI 中更常用的方式,因为它能自动处理布局,非常适合制作工具窗口。
- GUILayout.Toolbar返回一个int,代表当前选中的标签索引。

1.6 在编辑器窗口中使用GUI
IMGUI 的核心优势在此处得以充分体现,这也是其最典型的应用场景。需要注意的是,以下脚本不能直接附加到游戏对象上,而是需要专门编写编辑器脚本。
具体操作步骤如下:
- 在项目中新建名为"Editor"的文件夹(名称必须严格保持一致)
- 在该文件夹内创建以下 C# 脚本:CustomToolWindow
// 注意:继承自 EditorWindow,不是 MonoBehaviour
public class CustomToolWindow : EditorWindow
{
private string creatorName = "Your Name";
private GameObject targetObject;
// 添加菜单项
[MenuItem("Tool/My Custom Tool")]
public static void ShowWindow()
{
// 获取一个自定义窗口的实例
GetWindow<CustomToolWindow>("My Tool");
}
// 这是编辑器窗口的 IMGUI 绘制代码
private void OnGUI()
{
GUILayout.Label("Object Creator Tool", EditorStyles.boldLabel);
// 使用 EditorGUILayout 获取更符合编辑器风格的控件
creatorName = EditorGUILayout.TextField("Creator Name", creatorName);
targetObject = (GameObject)EditorGUILayout.ObjectField("Target Object", targetObject, typeof(GameObject), true);
EditorGUILayout.Space();// 添加一些空行
if (GUILayout.Button("Creat Cube"))
{
CreatePrimitive(PrimitiveType.Cube);
}
if (GUILayout.Button("Creat Sphere") && targetObject != null)// 设置控件是否可交互
{
CreatePrimitive(PrimitiveType.Sphere);
}
GUI.enabled = true;// 恢复可用状态
}
void CreatePrimitive(PrimitiveType type)
{
GameObject go = GameObject.CreatePrimitive(type);
go.name = creatorName + "s+" + type.ToString();
// 将此操作注册到撤销系统中
Undo.RegisterCreatedObjectUndo(go, "Create" + type.ToString());
// 在编辑器中选中新创建的对象
Selection.activeObject = go;
}
}
代码说明:
- [MenuItem("Tools/My Custom Tool")]:在 Unity 编辑器顶部菜单栏的Tools下创建一个名为My Custom Tool的菜单项。
- EditorWindow:自定义编辑器窗口的基类。
- EditorGUILayout:提供了与 Unity 编辑器风格一致的控件,如ObjectField用于拖拽选择场景中的对象,TextField带有一个标签等。
- Undo.RegisterCreatedObjectUndo:将创建对象的操作注册到撤销历史中,用户可以按Ctrl+Z撤销。
- Selection.activeObject:在 Hierarchy 或 Project 窗口中选择指定的对象。
- 运行后,点击Tools > My Custom Tool即可打开自定义的工具窗口。
2 UGUI
2.1 UGUI简介
UGUI(Unity Graphical User Interface)是 Unity 内置的官方 UI 系统,自 Unity 4.6 版本推出后逐步替代了第三方的 NGUI,成为 Unity 项目中最主流的 UI 解决方案。它深度集成于 Unity 编辑器,支持 2D/3D 场景适配,具备灵活的布局、交互和渲染能力,适用于游戏菜单、HUD、对话框、移动应用界面等各类 UI 开发场景。
2.2 UGUI组成
UGUI 的核心是「Canvas(画布)+ UI 控件 + EventSystem(事件系统) 」的三层结构,所有 UI 逻辑都围绕这三者展开。
2.2.1 Canvas
Canvas(画布)是UI 的容器,所有 UI 元素必须作为 Canvas 的子物体才能显示,Canvas 是 UI 渲染的 “载体”,负责管理 UI 的渲染顺序、相机适配等。当你通过菜单GameObject > Create UI首次创建 UI 元素时,如果场景中还没有画布,Unity 会自动创建一个。

2.2.1.1 Canvas 组件
Canvas 定义了 UI 元素被绘制的虚拟空间,其行为主要由 渲染模式(Render Mode) 控制。可以根据游戏的需要,在三种不同的渲染模式中选择,它们决定了 UI 与游戏场景的交互方式。

Canvas 的三种渲染模式(Render Mode):
| 渲染模式 | 工作原理 | 适用场景 | 注意事项 |
|---|---|---|---|
| Screen Space - Overlay (屏幕空间-覆盖) | UI直接绘制在屏幕上,无需摄像机,始终位于其他图形之上。 | 传统的、始终位于顶层的2D UI,如手游的虚拟按键、设置菜单。 | 此模式的画布必须位于层级视图(Hierarchy)的顶级,否则UI可能消失。 |
| Screen Space - Camera (屏幕空间-摄像机) | UI被绘制在指定摄像机前方一定距离的平面上,受摄像机参数(如视野)影响。 | 需要与场景有简单透视关系的UI,如VR游戏中的界面、游戏中的头盔显示器效果。 | UI的屏幕大小不随距离变化,但会被摄像机与UI平面之间的3D对象遮挡。 |
| World Space (世界空间) | UI作为场景中的一个普通3D对象渲染,可以任意旋转和放置。 | 需要与游戏世界交互的"叙事界面",如游戏中的显示屏、漂浮在角色头上的血条、世界中的告示牌。 | 画布在屏幕上的大小取决于摄像机的视角和距离,需要手动调整Rect Transform来确定大小。 |
Pixel Perfect:仅Screen Space模式,启用后平滑边缘,减少锯齿,使UI显示更清晰。
注意:
- 在同一个 Canvas 下,UI 元素的绘制顺序(即谁覆盖谁)遵循一个简单规则:按照它们在 Hierarchy 视图中的排列顺序,从上到下依次绘制。排在下面的元素会覆盖在上面的元素之上。
- 你可以通过直接拖拽调整元素在 Hierarchy 中的顺序,或者使用脚本中的 SetAsFirstSibling()、SetAsLastSibling() 和 SetSiblingIndex()方法来动态控制顺序。
2.1.2.2 Canvas Scaler 组件

Canvas Scaler组件确保你的UI在不同分辨率和屏幕尺寸下都能有合适的显示效果。它的核心是UI Scale Mode 属性:
Constant Pixel Size(恒定像素大小):UI元素保持固定的像素尺寸。你可以通过Scale Factor 整体缩放画布内的所有元素。
Scale With Screen Size(随屏幕尺寸缩放):这是最常用的模式,可根据预设的参考分辨率(Reference Resolution)进行缩放。当屏幕分辨率大于参考分辨率时UI会放大,小于则会缩小。通过Screen Match Mode(如Expend、Shrink、Match Width or Height)可以调整宽高比不适配时的缩放策略。
Constant Physical Size(恒定物理尺寸):使UI元素在不同设备上保持相同的物理大小(如英寸、毫米)。此模式需要设备能正确报告其DPI。
2.1.2.3 Graphic Raycaster 组件
Graphic Raycaster是挂在Canvas上负责处理UI交互(如点击、悬停)的组件。

Ignore Reversed Graphics:通常建议启用。启用后,只有当图形正面朝向你时才能被射线击中,背对你的UI元素不会被误触发。
Blocking Objects & Blocking Mask:这两个属性用于设置哪些类型的非UI对象(如3D模型或2D碰撞体)可以阻挡UI射线。例如,你可以设置让一个3D角色模型走到UI前面时,遮挡住后面的UI按钮,使其无法被点击。
2.2.2 EventSystem
EventSystem是UI 交互的核心,用于处理 UI 的输入事件(鼠标点击、触摸、键盘输入等),是按钮、输入框等交互 UI 生效的前提。
新建 UI 元素时,Unity 会自动创建EventSystem物体(包含 EventSystem 和Standalone Input Module / Touch Input Module组件),无需手动创建。

下面这个流程图概括了其核心工作机制:

EventSystem 是整个事件系统的大脑和协调中心,它的主要职责包括:
管理输入模块:EventSystem 会在每帧更新时,查看所有可用的输入模块,并决定使用哪一个来处理当前活动,一个场景中通常只需要一个 EventSystem 对象
管理选中对象:它负责跟踪当前被选中的GameObject,这对于UI导航(例如通过键盘或手柄切换焦点)至关重要。
协调射线投射:它协助输入模块,利用配置在场景中的射线投射器来确定指针指向的位置。
2.2.2.1 EventSystem 组件

属性如下:
First Selected:指定游戏启动时默认选中的GameObject,这对于手柄或键盘操作确定初始焦点非常有用。
Send Navigation Events:控制事件系统是否允许发送导航事件(移动、提交、取消)。
Drag Threshold:拖拽操作的容限区域(以像素为单位),用于判断一个指针移动是否构成拖拽。
2.2.2.2 Standalone Input Module 组件

Standalone Input Module是专门为处理鼠标、键盘和控制器输入而设计的模块。它的工作严重依赖于Unity的 Input Manager。
Horizontal/Vertical Axis:指定输入管理器中用于水平/垂直导航轴的名称。
Submit/Cancel Button:指定输入管理器中用于提交和取消操作的按钮名称。
Input Actions Per Second:每秒允许的键盘/控制器输入事件的最大数量,用于限制事件触发频率。
Repeat Delay:在每秒输入操作重复率生效前,系统等待的延迟时间(以秒为单位)。
Force Module Active:即使模块本身认为自己不应被激活,也强制让其处于活动状态。
事件处理流程:
1.新的按压发生时,模块会按顺序发送:
PointerEnter事件(给所有可处理该事件的层级中的对象)
PointerPress事件
缓存拖动处理程序(层级中第一个能处理拖动的元素)
向缓存的拖动处理程序发送BeginDrag事件
在事件系统中将 "Pressed" 对象设置为Seleted(选中状态)
2.持续按压时,模块会处理移动,并向缓存的拖动处理程序发送Drag事件。如果触摸在对象之间移动,还会处理 PointerEnter和 PointerExit事件。
3.释放操作时,模块会:
向收到 PointerPress的对象发送 PointerUp事件。
如果当前悬停的对象与之前按下的对象相同,则发送 PointerClick事件。
如果有缓存的拖动处理程序,则发送Drop事件,最后发送 EndDrag事件。
2.2.3 Rect Transform
Rect Transform 是 Unity UGUI 系统中所有 UI 元素的基础变换组件,它继承自常规的 Transform,但专门为 2D 用户界面进行了优化和扩展。

Rect Transform 与常规 Transform 的区别
| 特性 | Transform | Rect Transform |
|---|---|---|
| 坐标系 | 3D 世界坐标系 | 2D 矩形坐标系 |
| 定位方式 | 位置、旋转、缩放 | 锚点、轴心点、尺寸 |
| 适用对象 | 3D 物体、2D 精灵 | 专为 UI 元素设计 |
| 父子关系 | 基于世界/本地坐标 | 基于矩形相对定位 |
2.2.3.1 位置与尺寸属性
根据锚点设置的不同,Inspector 中显示的属性会发生变化:
当锚点为点(非拉伸)时:
Pos X, Pos Y, Pos Z:相对于轴心点的位置
Width, Height:元素的固定宽度和高度
当锚点为线或面(拉伸)时:
Left, Right, Top, Bottom:元素各边与父容器对应边的距离
Pos Z:Z 轴位置(用于层级排序)
2.2.3.2 Anchors 锚点
锚点是 Rect Transform 最重要的概念,它定义了 UI 元素与其父元素的相对定位关系。
锚点预设模式:
左上/右上/左下/右下角:元素固定在父容器的某个角落
顶部/底部/左/右拉伸:元素紧贴父容器的某一边
中心/水平中心/垂直中心:元素相对于父容器中心定位
全面拉伸:元素填充整个父容器
自定义锚点:
Min:左下角锚点 (X, Y)
Max:右上角锚点 (X, Y)
数值范围:0 到 1(相对父容器的标准化坐标)
2.2.3.3 Pivot 轴心点
轴心点决定了元素的旋转中心、缩放中心和定位基准点。
Pivot X, Y:取值范围 0-1
例如:(0, 0) = 左下角,(0.5, 0.5) = 中心,(1, 1) = 右上角
轴心点会影响元素的位置计算和变换效果
2.3 基础控件
2.3.1 Text 控件
2.3.1.1 属性介绍

Text: 实际显示的文本字符串。支持多行文本,使用换行符(\n)进行换行。
Font: 文本所使用的字体。可以是Unity内置字体,也可以是自定义字体。
Font Style: 字体样式
- Normal(正常)
- Bold(粗体)
- Italic(斜体)
- BoldAndItalic(粗斜体)
Font Size: 字体大小。注意,如果“Auto Size”启用,则字体大小将自动调整,此属性将变为只读。
Line Spacing: 行间距,表示多行文本的行与行之间的间距。
Rich Text: 是否支持富文本。启用后,可以使用HTML风格的标签来设置文本中部分内容的样式(如颜色、大小、粗体等)。
Alignment: 文本的对齐方式
- 水平对齐:左、中、右
- 垂直对齐:上、中、下
Align By Geometry: 使用几何体对齐,当启用时,文本将根据字体的几何信息进行对齐,而不是字体矩阵。通常用于使字体看起来更紧凑。
Horizontal Overflow: 水平溢出模式。有两种模式:
- Wrap:当文本宽度超过RectTransform的宽度时自动换行。
- Overflow:文本超出RectTransform宽度时继续显示,不会被裁剪。
Vertical Overflow: 垂直溢出模式。有两种模式:
- Truncate:当文本高度超过RectTransform的高度时,超出部分被裁剪。
- Overflow:文本超出RectTransform高度时继续显示,不会被裁剪。
Best Fit: 自动调整字体大小以适应RectTransform的尺寸。启用后,可以设置最小和最大字体大小。
Color: 文本的颜色。
Material: 文本的材质,默认使用字体材质。
Raycast Target: 是否作为射线投射目标(即是否响应鼠标事件)。如果不需要文本被点击,可以禁用此属性以提高性能。
2.3.1.2 案例:打字机效果
将本脚本赋给Text游戏对象即可,可以通过调整charsPerSecond控制打印频率。
using UnityEngine.UI;
public class DaZiJi : MonoBehaviour
{
private Text textComponent;
private float charsPerSecond = 10f;//打印频率
void Start()
{
textComponent = GetComponent<Text>();
string printText = "沁园春·雪\n北国风光,千里冰封,万里雪飘。\n" +
"望长城内外,惟余莽莽;大河上下,顿失滔滔。山舞银蛇,原驰蜡象,欲与天公试比高。\n" +
"须晴日,看红装素裹,分外妖娆。江山如此多娇,引无数英雄竞折腰。\n" +
"惜秦皇汉武,略输文采;唐宗宋祖,稍逊风骚。一代天骄,成吉思汗,只识弯弓射大雕。\n" +
"俱往矣,数风流人物,还看今朝。";
StartCoroutine(TypeText(printText));
}
public IEnumerator TypeText(string fullText)
{
textComponent.text = "";
for (int i = 0; i < fullText.Length; i++)
{
textComponent.text += fullText[i];
yield return new WaitForSeconds(1f / charsPerSecond);
}
}
}

2.3.1.3 TextMeshPro
虽然 UGUI Text 组件功能完善,但对于高质量文本渲染,建议考虑使用 TextMeshPro:
| 特性 | UGUI Text | TextMeshPro |
|---|---|---|
| 文本质量 | 一般 | 极佳(Signed Distance Field) |
| 性能 | 中等 | 优化更好 |
| 功能丰富度 | 基础 | 非常丰富 |
| 学习曲线 | 简单 | 稍复杂 |
TextMeshPro 基本用法:
public class TMPExample : MonoBehaviour
{
public TextMeshProUGUI tmpText;
void Start()
{
tmpText.text = "这是 TextMeshPro 文本";
tmpText.fontSize = 24;
tmpText.color = Color.red;
}
}
2.3.2 Image 控件
Image组件是UGUI系统中用于显示图像的基本组件,它可以显示精灵(Sprite)、简单的颜色块或者通过材质(Material)实现特效。

| 属性 | 功能说明 | 默认值 |
|---|---|---|
| Source Image | 源图像精灵(Sprite) | None |
| Color | 图像颜色(与源图像相乘) | 白色 |
| Material | 渲染材质 | None |
| Raycast Target | 是否接收射线检测 | 开启 |
| Image Type | 图像显示类型 | Simple |
| Preserve Aspect | 保持宽高比 | 关闭 |
| Set Native Size | 设置为原始尺寸按钮 | - |
| Fill Method | 填充方法(仅填充类型) | Radial 360 |
| Fill Origin | 填充起点 | Top |
| Fill Amount | 填充量 | 1 |
1. Source Image(源图像)
描述:指定要显示的精灵(Sprite)。如果没有指定,Image将显示为纯色块。
注意:只能指定为Sprite类型的资源。
2. Color(颜色)
描述:用于与源图像颜色相乘的颜色值。默认值为白色(RGB(255,255,255)),表示不改变原图颜色。如果设置为其他颜色,则会与图像颜色进行混合。
3. Material(材质)
描述:用于渲染图像的材质。默认使用UI默认材质。可以指定自定义材质来实现特殊效果(如描边、阴影、发光等)。
4. Raycast Target(射线检测目标)
描述:如果启用,该图像可以作为射线检测的目标,即可以响应鼠标/触摸事件。如果不需要响应事件,可以禁用以提高性能。
5. Image Type(图像类型)
描述:定义图像的显示方式。有以下几种类型:
Simple(简单):拉伸整个图像以填充整个矩形区域。
Sliced(切片):使用9宫格切片(9-slicing)来拉伸图像,保持角落不变形,适用于按钮背景等。
Tiled(平铺):平铺图像,类似于Simple,但如果图像尺寸小于矩形区域,则会平铺。注意:如果图像有边框(Border),则平铺中间部分。
Filled(填充):以某种填充方式显示图像的一部分,常用于技能冷却、血条等。
6. Preserve Aspect(保持宽高比)
描述:仅在Image Type为Simple时可用。如果启用,将保持图像的原始宽高比,防止图像变形。
7. Set Native Size(设置为原始大小)
描述:点击此按钮将Image的RectTransform尺寸设置为源图像的原始尺寸。
2.3.3 Raw Image 控件
2.3.3.1 属性介绍
Raw Image 组件是 Unity UGUI 系统中用于直接显示纹理(Texture) 的组件,与 Image 组件使用 Sprite 不同,Raw Image 直接操作纹理资源,提供了更灵活的纹理显示能力。

Raw Image 与 Image 的核心区别
| 特性 | Image 组件 | Raw Image 组件 |
|---|---|---|
| 资源类型 | 使用 Sprite | 直接使用 Texture |
| 9-slice 缩放 | 支持(Sliced 模式) | 不支持 |
| 图集支持 | 完整支持 | 不支持 |
| 性能开销 | 相对较高 | 相对较低 |
| 使用场景 | UI 图标、按钮、精灵 | 视频、动态纹理、渲染纹理 |
Raw Image 属性
| 属性 | 功能说明 | 默认值 |
|---|---|---|
| Texture | 源纹理资源 | None |
| Color | 颜色叠加(与纹理相乘) | 白色 |
| Material | 渲染材质 | None |
| Raycast Target | 是否接收射线检测 | 开启 |
| UV Rect | 纹理 UV 坐标调整 | (0,0,1,1) |
2.3.3.2 案例:小地图制作
核心思路是让一个专门的摄像机拍摄游戏场景,将实时画面显示在UI的Raw Image上。
创建小地图摄像机:
在场景中创建一个新的摄像机,重命名为“MiniMapCamera”。调整它的位置和旋转角度(通常放在场景上空,旋转X轴90度俯视),在摄像机组件中,将Projection设置为Orthographic(正交投影,无透视变形),并根据需要调整Size参数。创建 Render Texture:
在Project视图右键 -> Create -> Render Texture,命名为“MiniMapRenderTexture”。选中刚创建的Render Texture,在Inspector中可以根据需要调整尺寸、抗锯齿等参数。然后将此Render Texture拖拽到MiniMapCamera摄像机的Target Texture字段中。创建小地图UI:
在Hierarchy视图右键 -> UI -> Raw Image,这将自动创建Canvas并将Raw Image加入其中。选中Raw Image,在Inspector里将其Texture设置为前面创建的“MiniMapRenderTexture”。通过Rect Tool调整Raw Image在屏幕上的位置和大小(通常放在右上角)。创建脚本:MiniMapCameraFollow,赋给MiniMapCamera,将Player游戏对象拖在playerTarget位置。
MiniMapCameraFollow脚本:
public class MiniMapCameraFollow : MonoBehaviour
{
public Transform playerTarget; // 拖拽玩家对象到此
private Vector3 offset;
void Start()
{
// 计算初始偏移,通常是小地图摄像机与玩家的高度差
offset = transform.position - playerTarget.position;
// 确保小地图摄像机只在X和Z轴上跟随,保持Y轴(高度)不变
offset.y = transform.position.y;
}
void LateUpdate()
{
// 更新摄像机位置,只同步玩家的x和z坐标
transform.position = new Vector3(playerTarget.position.x, transform.position.y, playerTarget.position.z);
// 或者使用初始偏移:transform.position = playerTarget.position + offset;
}
}
注意:
- 性能:Render Texture的分辨率、抗锯齿等级等会影响性能,移动端需注意
- Audio Listener冲突:确保小地图摄像机上没有Audio Listener组件,通常主摄像机上有且只有一个即可。
2.4 组合控件
2.4.1 Button 控件
2.4.1.1 属性介绍
Button(按钮)是Unity UGUI系统中最常用的交互控件之一,它允许用户通过点击、触摸或键盘/手柄事件来触发操作。Button 组件继承自Selectable类,因此它拥有所有可选中 UI 元素的通用属性,并添加了特定的点击事件功能。

1.基本属性
Interactable(交互性): 布尔值,决定按钮是否可交互。如果取消勾选,按钮将进入禁用状态,不会响应输入。
Transition(过渡): 定义按钮在不同状态(普通、高亮、按下、禁用)下的外观变化方式。有四种模式:
None: 无过渡。
Color Tint: 颜色渐变(默认)。通过修改颜色来表现状态变化。
Sprite Swap: 精灵切换。为每个状态指定不同的精灵。
Animation: 动画过渡。使用动画控制器来定义状态变化。
Navigation(导航): 定义如何使用键盘、手柄或方向键在UI元素之间导航。选项包括:
None: 无导航。
Horizontal: 水平导航。
Vertical: 垂直导航。
Automatic: 自动导航。
Explicit: 明确指定上下左右导航的目标。
2. 颜色过渡(Color Tint)模式下的属性
当Transition设置为Color Tint时,会出现以下属性:
Target Graphic: 应用颜色过渡的目标图形(通常是一个Image或Text)。
Normal Color: 正常状态的颜色。
Highlighted Color: 高亮状态的颜色(当鼠标悬停时)。
Pressed Color: 按下状态的颜色(当按钮被按下时)。
Disabled Color: 禁用状态的颜色。
Color Multiplier: 颜色倍增器,与颜色值相乘,可用于增强颜色效果。
Fade Duration: 颜色过渡的持续时间(以秒为单位)。
3. 精灵切换(Sprite Swap)模式下的属性
当Transition设置为Sprite Swap时,会出现以下属性:
Target Graphic: 应用精灵切换的目标图形(通常是一个Image)。
Highlighted Sprite: 高亮状态的精灵。
Pressed Sprite: 按下状态的精灵。
Disabled Sprite: 禁用状态的精灵。
4. 动画过渡(Animation)模式下的属性
当Transition设置为Animation时,会出现以下属性:
Normal Trigger: 正常状态的动画触发器。
Highlighted Trigger: 高亮状态的动画触发器。
Pressed Trigger: 按下状态的动画触发器。
Disabled Trigger: 禁用状态的动画触发器。
Auto Generate Animation: 自动生成动画控制器(如果尚未存在)。
5. 按钮特有属性
On Click (): 点击事件列表。当按钮被点击并释放时触发(即完整的点击操作)。你可以通过此事件列表添加回调函数。
2.4.1.2 交互性
public Button myButton;
void Start()
{
// 启用/禁用按钮交互
myButton.interactable = true;
// 检查按钮是否可交互
bool canInteract = myButton.IsInteractable();
}
2.4.1.3 使用方式
1.AddListener 添加事件监听
public Button myButton;
void Start()
{
// 通过AddListener添加监听
myButton.onClick.AddListener(MyButtonClick);
}
void MyButtonClick()
{
Debug.Log("按钮被点击了!");
}
// 注意:在适当的时候移除监听,以免重复添加或内存泄漏
void OnDestroy()
{
myButton.onClick.RemoveListener(MyButtonClick);
}
2. 匿名函数 添加事件监听
public Button myButton;
void Start()
{
myButton.onClick.AddListener(() =>
{
Debug.Log("按钮被点击,使用Lambda表达式");
// 这里可以写更多处理逻辑
});
}
2.4.2 Toggle 控件
2.4.2.1 属性介绍
Toggle(开关/复选框)是 Unity UGUI 系统中用于实现二元选择的交互控件,允许用户在开启/关闭状态之间切换。它在设置菜单、选项选择和功能开关等场景中广泛应用。
Toggle组件继承自Selectable类,拥有与 Button 类似的交互属性,并添加了特定的开关状态功能。

| 属性 | 功能说明 | 默认值 |
|---|---|---|
| Is On | 当前开关状态 | false |
| Toggle Transition | 状态切换过渡效果 | Fade |
| Graphic | 显示开关状态的图像 | None |
| Group | 所属的 Toggle Group | None |
| Interactable | 是否可交互 | true |
| On Value Changed | 值改变事件回调 | 空 |
- Is On:表示Toggle当前是否处于开启状态(打勾状态)。默认值为false。
- Toggle Transition:切换时的过渡效果,有两种选项:
- None:立即切换,无过渡效果。
- Fade:使用淡入淡出效果进行切换。
- Graphic:用于显示Toggle开关状态的图像(例如,打勾的图片)。通常是一个Checkmark图像。
- Group:Toggle组,可以将多个Toggle放在一个组中,实现单选效果(即同时只能有一个Toggle被选中)。
其他继承自Selectable的属性
- Interactable:是否可交互。
- Transition:状态过渡效果(颜色过渡、精灵过渡、动画过渡)。
- Navigation:导航设置。
2.4.2.2 使用方式
public class ToggleController: MonoBehaviour
{
public Toggle toggle;
public bool enableLogging = true;
void Start()
{
if (toggle == null)
toggle = GetComponent<Toggle>();
if (toggle != null)
toggle.onValueChanged.AddListener(OnToggleChanged);
}
void OnToggleChanged(bool isOn)
{
if (enableLogging)
Debug.Log("Toggle is "+ (isOn ? "ON" : "OFF"));
if (isOn)
EnableFeature();
else
DisableFeature();
}
void EnableFeature()
{
// 开启功能的代码
}
void DisableFeature()
{
// 关闭功能的代码
}
//在销毁时移除事件监听
void OnDestroy()
{
if (toggle != null)
toggle.onValueChanged.RemoveListener(OnToggleChanged);
}
}
2.4.3 InputField 控件
2.4.3.1 属性介绍
InputField(输入框)是UGUI中用于处理用户文本输入的重要组件,它允许用户通过键盘或触摸输入文本。InputField 组件提供了丰富的属性来控制文本输入的行为和外观。

1. Text Component (文本组件)
类型:Text
说明:用于显示输入文本的Text组件。通常这是InputField子对象中的一个Text组件。
2. Text (文本)
类型:string
说明:输入框中当前显示的文本。可以通过代码获取或设置。
3. Character Limit (字符限制)
类型:int
说明:允许输入的最大字符数。0表示无限制。
4. Content Type (内容类型)
类型:ContentType枚举
说明:指定输入内容的类型,用于验证和输入限制。常见选项包括:
Standard:任何字符。
Autocorrected:自动校正。
Integer Number:只允许整数。
Decimal Number:允许小数。
Alphanumeric:字母和数字。
Name:人名,首字母大写。
Email Address:电子邮件地址。
Password:密码,显示为星号。
Pin:PIN码,显示为星号,且通常为数字。
Custom:自定义,可以设置行类型、输入类型、键盘类型等。
5. Line Type (行类型)
类型:LineType枚举
说明:指定文本的换行行为。
Single Line:单行,不换行。
Multi Line Submit:多行,但按提交键(如Enter)时提交。
Multi Line Newline:多行,按提交键时换行。
6. Placeholder (占位文本)
类型:Graphic
说明:当输入框为空时显示的占位文本(通常为灰色提示文字)。通常是一个Text组件,但也可以是其他Graphic。
7. Caret Blink Rate (光标闪烁速率)
类型:float
说明:光标闪烁的频率(以秒为单位)。0表示不闪烁。
8. Caret Width (光标宽度)
类型:int
说明:光标的宽度(像素)。
9. Custom Caret Color (自定义光标颜色)
类型:bool
说明:是否使用自定义光标颜色
10. Selection Color (选中颜色)
当选中文本时,文本背景的颜色。
11. On Value Changed (值改变事件)
- 当输入框的文本内容发生变化时触发的事件
12. End Edit (结束编辑事件)
- 当用户完成编辑(例如按下提交键或点击输入框外部)时触发的事件。
2.4.3.2 使用方式
1.监听值改变事件
public class InputFieldController : MonoBehaviour
{
public InputField myInputField;
void Start()
{
myInputField.onValueChanged.AddListener(OnInputValueChanged);
}
void OnInputValueChanged(string newText)
{
Debug.Log("输入框内容改变为: " + newText);
}
}
2.监听结束编辑事件
public class InputFieldController : MonoBehaviour
{
public InputField myInputField;
void Start()
{
myInputField.onEndEdit.AddListener(OnInputEndEdit);
}
void OnInputEndEdit(string finalText)
{
Debug.Log("用户完成编辑: " + finalText);
}
}
2.4.3.3 案例:注册登陆界面实现
点击下面链接,查看具体详细应用教程!
Unity注册登陆UI界面功能 PlayerPrefs +UGUI
2.4.3.4 案例:DeepSeek AI对话
点击下面链接,查看具体详细应用教程!
2.4.4 Slider 控件

2.4.4.1 属性介绍
Interactable:布尔值,决定Slider是否可交互。
Transition:定义Slider在不同状态(正常、高亮、按下、禁用)下的视觉过渡效果,选项包括None(无)、Color Tint(颜色 tint)、Sprite Swap(精灵交换)和Animation(动画)。
Navigation:定义导航顺序,用于控制器或键盘输入。
Fill Rect:用于显示填充区域的RectTransform。
Handle Rect:滑块手柄的RectTransform。
Direction:滑块的方向,包括从左到右、从右到左、从上到下、从下到上。
Min Value:滑块的最小值。
Max Value:滑块的最大值。
Whole Numbers:布尔值,如果为true,则滑块只能取整数值。
Value:滑块的当前值。
OnValueChanged:当滑块值改变时调用的UnityEvent,可以绑定自定义函数。
2.4.4.2 使用方式
public class SliderController : MonoBehaviour
{
public Slider mySlider;
void Start()
{
mySlider.onValueChanged.AddListener(OnSliderValueChanged);
}
void OnSliderValueChanged(float value)
{
Debug.Log("Slider value: " + value);
}
}
2.4.4.3 案例:音量控制
public class VolumeControl : MonoBehaviour
{
public Slider volumeSlider;
public Text volumeText;
void Start()
{
// 设置滑块范围
volumeSlider.minValue = 0f;
volumeSlider.maxValue = 1f;
// 加载保存的音量设置
volumeSlider.value = PlayerPrefs.GetFloat("MasterVolume", 0.8f);
// 绑定值改变事件
volumeSlider.onValueChanged.AddListener(SetVolume);
// 初始化显示
UpdateVolumeDisplay(volumeSlider.value);
}
void SetVolume(float volume)
{
// 设置全局音量
AudioListener.volume = volume;
// 保存设置
PlayerPrefs.SetFloat("MasterVolume", volume);
PlayerPrefs.Save();
// 更新显示
UpdateVolumeDisplay(volume);
}
void UpdateVolumeDisplay(float volume)
{
if (volumeText != null)
{
// 显示为百分比
volumeText.text = $"音量: {(volume * 100):F0}%";
}
}
void OnDestroy()
{
// 清理事件监听
if (volumeSlider != null)
volumeSlider.onValueChanged.RemoveListener(SetVolume);
}
}
使用说明:
场景设置:
在场景中创建一个 Slider(UI -> Slider)
创建一个 Text(UI -> Text)用于显示音量百分比
将这两个组件拖拽到脚本的对应字段中
功能特点:
滑块范围 0-1,对应音量 0%-100%
实时保存音量设置到 PlayerPrefs
启动时自动加载上次的音量设置
显示当前音量百分比
2.4.4.4 案例:进度条
点击下面链接,查看具体详细应用教程!
2.4.4.3 案例:血条
public class HealthBar : MonoBehaviour
{
public Slider healthSlider;
public Text healthText;
[Header("血量设置")]
public float maxHealth = 100f; //最大血量
public float currentHealth = 100f; //当前血量
void Start()
{
// 初始化血条
healthSlider.minValue = 0f;
healthSlider.maxValue = maxHealth;
healthSlider.value = currentHealth;
// 更新血量显示
UpdateHealthDisplay();
}
void Update()
{
//只用于测试,在实际游戏中可以通过组件的方式调用加血和扣血的方法
if (Input.GetKeyDown(KeyCode.H))
{
//测试 摁下H键,加血10
Heal(10f);
}
if (Input.GetKeyDown(KeyCode.J))
{
//测试 摁下H键,减血10
TakeDamage(10f);
}
}
// 受到伤害
public void TakeDamage(float damage)
{
currentHealth = Mathf.Max(0f, currentHealth - damage);
healthSlider.value = currentHealth;
UpdateHealthDisplay();
if (currentHealth <= 0f)
{
OnDeath();
}
}
// 恢复血量
public void Heal(float healAmount)
{
currentHealth = Mathf.Min(maxHealth, currentHealth + healAmount);
healthSlider.value = currentHealth;
UpdateHealthDisplay();
}
// 更新血量显示
void UpdateHealthDisplay()
{
if (healthText != null)
{
healthText.text = $"{currentHealth:F0}/{maxHealth:F0}";
}
}
// 死亡处理
void OnDeath()
{
Debug.Log("角色死亡!");
// 在这里添加死亡逻辑,比如播放动画、游戏结束等
}
// 重置血量
public void ResetHealth()
{
currentHealth = maxHealth;
healthSlider.value = currentHealth;
UpdateHealthDisplay();
}
}
具体步骤:
在 Canvas 下创建 Slider (UI -> Slider)
调整 Slider 外观:
删除 Handle Slide Area(不需要拖动把手)
设置 Fill 为绿色,Background 为红色或灰色
创建 Text (UI -> Text) 显示血量数值
将这两个组件拖拽到脚本的对应字段
测试:可以通过摁下J键加血,摁下K键扣血
2.4.5 ScrollBar 控件
ScrollBar(滚动条)是 Unity UGUI 系统中用于控制内容滚动位置的交互组件。ScrollBar 通常与 ScrollRect 组件配合使用,但也可以独立用于控制自定义的滚动逻辑。

| 属性 | 功能说明 | 默认值 |
|---|---|---|
| Handle Rect | 滑动把手的 RectTransform | - |
| Direction | 滚动条方向 | Bottom To Top |
| Value | 当前滚动值 (0-1) | 0 |
| Size | 把手大小 (0-1) | 0.2 |
| Number Of Steps | 步进数量 | 0 |
| OnValueChanged | 值改变事件 | - |
2.4.6 ScrollView 控件
2.4.6.1 属性介绍
ScrollView(滚动视图)是一个在应用和游戏开发中常见的UI组件,用于在有限的显示区域内浏览更多内容。
内容滚动:当内容(如长文本、图片列表等)超过容器大小时,ScrollView 提供垂直或水平滚动功能。
手势支持:支持拖拽、惯性滚动等手势操作,提升用户体验。
可视化指示:通常与滚动条(ScrollBar)结合,显示当前滚动位置。

ScrollView 的行为和外观可以通过一系列属性进行配置。以下是跨平台常见的属性(以 Unity 的 UGUI ScrollView 为例):
| 属性 | 功能说明 | 常见取值/类型 |
|---|---|---|
| Content | 滚动的内容容器,通常是一个包含所有子元素的父节点。 | RectTransform (Unity) |
| Horizontal | 是否允许水平滚动。 | bool (默认: false) |
| Vertical | 是否允许垂直滚动。 | bool (默认: true) |
| Movement Type | 滚动运动类型,如弹性滚动(Elastic)或受限(Clamped)。 | 枚举类型 |
| Elasticity | 弹性效果强度,当内容滚动到边界后继续拖拽时的回弹效果。 | float (默认: 0.1) |
| Inertia | 是否开启惯性滚动,手指离开后内容继续滚动。 | bool (默认: true) |
| Deceleration Rate | 惯性滚动时的减速度,值越大停止越快。 | float (0~1, 默认: 0.135) |
| Scroll Sensitivity | 滚动灵敏度,对手势滚动的响应速度。 | float |
| Viewport | 定义可视区域的遮罩,通常与 Mask 组件配合使用。 | RectTransform |
| OnValueChanged | 滚动值变化时的事件回调,可用于监听滚动位置。 | UnityEvent |
2.4.6.2 案例:背包功能制作

制作步骤:
第1步:创建背包UI基础结构
在 Hierarchy 面板右键 → UI → Scroll View,命名为 InventorySystem
调整 ScrollView 组件设置:
取消勾选 Horizontal(我们只需要垂直滚动)
确保 Vertical 保持勾选
将 Movement Type 设置为 Elastic(弹性效果更自然)
设置 Viewport 的锚点为 stretch(全屏拉伸),确定可见区域

第2步:配置背包内容容器
选中 Content 对象,添加以下组件:
Grid Layout Group(网格布局):自动排列物品格子
Content Size Fitter(内容尺寸适配):Vertical Fit 设置为 Preferred Size
配置 Grid Layout Group:
Cell Size: 80, 80 每个格子的尺寸
Spacing: 10, 10 格子间距
Start Corner: Upper Left 从左上角开始排列
Start Axis: Horizontal 水平方向优先排列
Constraint: Flexible 灵活布局

第3步:创建物品格子预制体
1.右键 Content → UI → Image,命名为 InventorySlot
2.设置格子外观,给InventorySlot添加组件:
- 添加 Image 组件,选择边框样式精灵图
- 添加 Button 组件(用于交互)
3.给 InventorySlot 创建子对象:
- ItemIcon (Image):显示物品图标
- ItemCount (Text):显示物品数量
4.将脚本InventorySlot.cs赋给InventorySlot,并将子物体ItemIcon和ItemCount拖入对应位置
5.将 InventorySlot 拖入 Project 窗口创建为预制体备用

第4步:设置背包管理器
- 创建空物体 InventoryManager
- 添加 InventoryManager.cs脚本
- Content Parent: 拖入 ScrollView 的 Content

第5步:设置游戏管理器
- 创建空物体 GameController
- 添加 GameController.cs脚本
- Inventory: 拖入InventoryManager
- 四个Icon需要自行搜图导入Unity的Project视图,并修改Texture Type为Sprite(2D and UI)格式,才能使用


第6步:配置物品容器
将InventorySlot预制体作为子物体拖放在Content下,不然会检测背包没有可存放物品的容器,无法添加物品。

代码如下:
1. ItemData.cs - 物品数据定义
作用:定义物品的基本信息和类型
放置位置:不需要挂载到游戏物体,纯粹的数据类
public enum ItemType
{
Consumable, //消耗品
Weapon, //武器
Material //材料
}
[System.Serializable]
public class ItemData
{
public string itemId;
public string itemName;
public Sprite icon;
public int count;
public ItemType type;
public ItemData(string id, string name, Sprite icon, int count, ItemType type)
{
this.itemId = id;
this.itemName = name;
this.icon = icon;
this.count = count;
this.type = type;
}
}
2. InventorySlot.cs - 单个物品格子
作用:控制每个背包格子的显示和点击交互
放置位置:背包格子预制体(每个格子一个)
/// <summary>
/// 库存槽位类,管理单个物品槽位的UI显示和交互
/// </summary>
public class InventorySlot : MonoBehaviour, IPointerClickHandler
{
[Header("UI组件")]
public Image itemIcon; // 物品图标显示组件
public Text countText; // 物品数量显示文本
private InventoryManager manager; // 库存管理器引用
private int slotIndex; // 当前槽位在库存中的索引
private ItemData currentItem; // 当前槽位存放的物品数据
/// <summary>
/// 初始化槽位
/// </summary>
/// <param name="mgr">库存管理器实例</param>
/// <param name="index">槽位索引号</param>
public void Setup(InventoryManager mgr, int index)
{
manager = mgr; // 设置库存管理器引用
slotIndex = index; // 设置槽位索引
ClearSlot(); // 初始化时清空槽位显示
}
/// <summary>
/// 更新槽位显示信息
/// </summary>
/// <param name="item">要显示的物品数据</param>
public void UpdateSlot(ItemData item)
{
currentItem = item; // 更新当前物品引用
// 如果物品存在且数量大于0,显示物品信息
if (item != null && item.count > 0)
{
itemIcon.sprite = item.icon; // 设置物品图标
itemIcon.color = Color.white; // 设置图标为完全显示
countText.text = item.count > 1 ? item.count.ToString() : ""; // 数量大于1时显示数量
}
else
{
ClearSlot(); // 否则清空槽位显示
}
}
/// <summary>
/// 清空槽位显示
/// </summary>
void ClearSlot()
{
itemIcon.sprite = null; // 移除图标
itemIcon.color = new Color(1, 1, 1, 0); // 设置图标完全透明
countText.text = ""; // 清空数量文本
}
/// <summary>
/// 处理鼠标点击事件
/// </summary>
/// <param name="eventData">指针事件数据</param>
public void OnPointerClick(PointerEventData eventData)
{
// 如果槽位为空,不处理点击
if (currentItem == null) return;
// 左键点击 - 使用物品
if (eventData.button == PointerEventData.InputButton.Left)
{
manager.UseItem(slotIndex);
}
// 右键点击 - 移除物品
else if (eventData.button == PointerEventData.InputButton.Right)
{
manager.RemoveItem(slotIndex);
}
}
}
3. InventoryManager.cs - 背包管理器
作用:管理整个背包系统,处理物品的添加、移除、使用等逻辑
放置位置:场景中的空物体,比如命名为"InventoryManager"
using UnityEngine.UI;
/// <summary>
/// 背包系统核心管理器
/// 负责物品的添加、删除、显示等功能
/// </summary>
public class InventoryManager : MonoBehaviour
{
[Header("背包设置")]
public Transform contentParent; // 包含所有格子预制体的父物体
private List<ItemData> items = new List<ItemData>();
private List<InventorySlot> slots = new List<InventorySlot>();
void Start()
{
// 初始化现有的格子
InitializeExistingSlots();
// 清空所有格子(可选)
ClearAllSlots();
}
// 初始化已经存在的格子预制体
void InitializeExistingSlots()
{
// 获取Content下所有的InventorySlot组件
InventorySlot[] existingSlots = contentParent.GetComponentsInChildren<InventorySlot>();
// 初始化每个格子
for (int i = 0; i < existingSlots.Length; i++)
{
existingSlots[i].Setup(this, i);
slots.Add(existingSlots[i]);
}
Debug.Log($"初始化了 {slots.Count} 个现有格子");
}
// 添加物品到背包
public void AddItem(ItemData newItem)
{
// 检查堆叠
foreach (ItemData item in items)
{
if (item.itemId == newItem.itemId)
{
item.count += newItem.count;
UpdateSlots();
return;
}
}
// 添加新物品
if (items.Count < slots.Count)
{
items.Add(newItem);
UpdateSlots();
}
else
{
Debug.Log("背包已满!");
}
}
// 移除物品
public void RemoveItem(int slotIndex)
{
if (slotIndex < items.Count)
{
items.RemoveAt(slotIndex);
UpdateSlots();
}
}
// 使用物品
public void UseItem(int slotIndex)
{
if (slotIndex < items.Count)
{
ItemData item = items[slotIndex];
Debug.Log($"使用了: {item.itemName}");
item.count--;
if (item.count <= 0)
{
RemoveItem(slotIndex);
}
else
{
UpdateSlots();
}
}
}
// 更新所有格子显示
void UpdateSlots()
{
for (int i = 0; i < slots.Count; i++)
{
ItemData item = i < items.Count ? items[i] : null;
slots[i].UpdateSlot(item);
}
}
// 清空所有格子
public void ClearAllSlots()
{
items.Clear();
UpdateSlots();
}
// 获取背包中物品数量
public int GetItemCount()
{
return items.Count;
}
// 获取背包容量
public int GetBackpackCapacity()
{
return slots.Count;
}
}
4.GameController.cs - 外部添加游戏物品
作用:添加指定Icon的游戏物体
放置位置:场景中的空物体,比如命名为"GameController"
public class GameController : MonoBehaviour
{
public InventoryManager inventory;
public Sprite HPIcon;
public Sprite MPIcon;
public Sprite ArmorIcon;
public Sprite WeaponIcon;
void Update()
{
// 按1键添加生命药水
if (Input.GetKeyDown(KeyCode.Alpha1))
{
ItemData newPotion = new ItemData("potion_1", "生命药水", HPIcon, 1, ItemType.Consumable);
inventory.AddItem(newPotion);
}
// 按2键添加魔法药水
if (Input.GetKeyDown(KeyCode.Alpha2))
{
ItemData newPotion = new ItemData("potion_2", "魔法药水", MPIcon, 1, ItemType.Consumable);
inventory.AddItem(newPotion);
}
// 按3键添加装备
if (Input.GetKeyDown(KeyCode.Alpha3))
{
ItemData newPotion = new ItemData("potion_3", "装备", ArmorIcon, 1, ItemType.Weapon);
inventory.AddItem(newPotion);
}
// 按4键添加武器
if (Input.GetKeyDown(KeyCode.Alpha4))
{
ItemData newPotion = new ItemData("potion_4", "武器", WeaponIcon, 1, ItemType.Weapon);
inventory.AddItem(newPotion);
}
}
}
2.4.7 DropDown 控件
2.4.7.1 属性介绍
Unity 的 DropDown 控件(也常被称为下拉菜单)是一个能让用户从预设列表中挑选单个选项的UI元素。它通过点击展开选项列表,选择后列表收起,只显示当前选中的选项,非常节省界面空间。

| 属性 | 说明 |
|---|---|
| Interactable | 控件是否可交互。 |
| Transition | 控件在不同状态(如正常、悬停、按下)间的视觉过渡效果。 |
| Navigation | 定义使用键盘或手柄导航时的切换顺序。 |
| Template | 下拉列表的模板 RectTransform,用于实例化选项列表。 |
| Caption Text | 用于显示当前选中选项文本的 Text 组件。 |
| Caption Image | 用于显示当前选中选项图像的 Image 组件。 |
| Item Text | 用于显示选项列表中每一项文本的 Text 组件。 |
| Item Image | 用于显示选项列表中每一项图像的 Image 组件。 |
| Value | 当前选中选项的索引(从0开始)。 |
| Options | 选项列表,每个选项可包含文本和图像。 |
2.4.7.2 使用方式
using UnityEngine.UI;
public class DropDownControl : MonoBehaviour
{
public Dropdown myDropdown;
void Start()
{
myDropdown.onValueChanged.AddListener(OnDropdownValueChanged);
}
private void OnDropdownValueChanged(int selectedIndex)
{
// 根据 selectedIndex 执行不同的逻辑
Debug.Log("选择了选项索引: " + selectedIndex);
switch (selectedIndex)
{
case 0:
// 处理选项1
break;
case 1:
// 处理选项2
break;
case 2:
// 处理选项3
break;
}
// 或者通过 dropdown.options[selectedIndex].text 获取选中文本
string selectedText = myDropdown.options[selectedIndex].text;
}
}
3 UI Toolkit
3.1 简介
UI Toolkit 是 Unity 推出的新一代跨平台 UI 框架,旨在替代传统的 IMGUI(即时模式 GUI)并补充 / 升级 UGUI(Unity GUI),核心定位是「编辑器扩展 + 运行时 UI 通用解决方案」。它基于现代 Web 技术思想(HTML/CSS/JS 分离模式),采用「结构 - 样式 - 逻辑分离」的设计,兼具高性能、跨平台兼容性和灵活的扩展性,是 Unity 官方推荐的未来 UI 开发标准。
1. 核心定位
「编辑器 + 运行时」双场景支持:既能开发 Unity 编辑器扩展(如自定义窗口、Inspector 面板),也能开发游戏内运行时 UI(如菜单、 HUD、弹窗)。
替代 IMGUI:解决 IMGUI 「无状态、绘制依赖代码执行」的局限性,提供更稳定的可视化编辑工作流。
补充 UGUI:优化 UGUI 「RectTransform 层级复杂、样式与逻辑耦合」的问题,提供更高效的布局和样式管理。
2. 设计目标
跨平台一致性:支持 PC、移动、主机、WebGL 等所有 Unity 支持的平台,UI 表现一致。
高性能:采用「Retained Mode(保留模式)」(UI 状态持久化,仅在变更时重绘),配合 GPU 加速、Draw Call 自动合并,性能优于 UGUI(尤其复杂 UI 场景)。
可视化工作流:提供 UI Builder 可视化编辑器,支持拖拽布局、实时预览,无需编写冗余代码。
分离关注点:结构(UXML)、样式(USS)、逻辑(C#)完全分离,便于团队协作和维护。
3.2 UI Toolkit 与 UGUI 的比较
选择合适的UI系统对项目至关重要。UI Toolkit和UGUI有各自的特点和适用场景。
|
特性/方面 |
UI Toolkit |
UGUI (Unity UI) |
|---|---|---|
|
架构与性能 |
基于保留模式的视觉内容树,适合复杂静态UI,在渲染大量元素时性能可能更优。 |
基于Canvas的即时模式,更适合动态变化频繁的UI。 |
|
开发体验 |
提供UI Builder可视化编辑,样式与逻辑分离(USS+UXML+C#),更接近现代Web开发。 |
主要依赖Scene视图拖拽编辑,样式与结构耦合。 |
|
学习曲线 |
有一定学习曲线,需了解USS/UXML及数据绑定等概念。 |
学习曲线相对平缓,概念对Unity开发者更熟悉。 |
|
主要应用场景 |
编辑器扩展、复杂的游戏UI(如模拟经营类游戏、Moba游戏技能UI)、Web风格应用。 |
动态UI(如血条、得分飘字)、快速原型开发、移动端简单UI。 |
3.3 UI Toolkit 核心概念与工作流
了解UI Toolkit的核心概念和工作流程,能更好地构建界面。
核心架构:UI Toolkit的根基是
VisualElement类。你可以将其理解为所有UI元素的基类,它构成了UI的视觉内容树。通过VisualElement的各种派生类(如Button,Label)以及创建自定义视觉元素,你可以构建出复杂的界面。样式与布局:USS 负责控制UI元素的外观,你可以定义如颜色、字体等样式属性。UXML 文件则用于定义用户界面的结构和层级关系,它使用一种类似HTML的标签语法来组织UI元素。响应式布局 机制可以让你创建的UI自动适应不同的屏幕尺寸。
数据处理与事件响应:UI Toolkit提供了数据绑定系统,可以将UI元素与游戏数据关联起来,实现数据的自动同步。事件处理 系统则用于响应各类用户交互。
开发工作流程:使用UI Toolkit创建UI的一般步骤是:首先在UI Builder 中通过拖放方式可视化地搭建UI结构并设置基本样式,这会产生相应的UXML和USS文件。然后,在C#脚本中引用这些资源,处理UI逻辑(如按钮点击响应),并将UI实例化显示给用户。
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐

所有评论(0)