说到Unity里的UI,你是不是经常听到两种声音:一种是“NGUI是经典,稳如老狗”,另一种是“UGUI是官方标配,别再用了”。我懂你,刚开始做项目的时候,我也在两个坑里反复横跳。今天咱们不扯那些虚头巴脑的理论,我就拿着这十几年折腾UI的经验,带你一步一步把NGUI摸透,顺便把UGUI该怎么选给你掰扯清楚。
先别急着新建工程,咱们先聊聊心里话。你现在是不是正对着空白场景发愁?左边看着NGUI的文档觉得古老,右边看着UGUI的新特性又觉得陌生?放心,这种情况太正常了。很多老手其实到现在还在用NGUI,尤其是在一些老项目或者对性能有极致要求的移动端游戏里。但如果你是个新手,想入坑或者转行,那咱们就得把这两样都搞清楚。
为什么我们还要回头看看NGUI?
你可能会问:“Unity官方都推UGUI那么多年了,NGUI不是早就停止更新了吗?为什么还要学它?”
这个问题问得好。确实,NGUI的最后一次大版本更新还是几年前的事情,官方早已不再维护。但为什么我还在文章里大篇幅讲它?原因很简单:有些坑,你绕过去才知道有多深。
NGUI的设计哲学和UGUI完全不同。UGUI是遵循了Unity官方标准的组件化设计,类似于HTML的DOM结构;而NGUI更像是一个独立的、高度封装的UI系统,它有自己的坐标系、自己的渲染逻辑、甚至自己的资源管理方式。
我见过太多新手,一上来就狂学UGUI,然后遇到性能瓶颈、兼容性问题、或者老项目维护需求时,完全懵圈。这时候如果懂一点NGUI的原理,你就能快速理解为什么某些UI操作会卡顿,为什么有些特效在UGUI里表现怪异。
更重要的是,很多商业游戏至今仍在运行NGUI。你在面试时如果被问到“你熟悉NGUI吗”,你说“只学过UGUI”,那可能就会失去一个机会。反之,如果你能说清楚NGUI和UGUI的区别,以及各自的适用场景,面试官会觉得你很有深度。
第一步:环境准备与NGUI基础认知
好,咱们正式开始。假设你现在已经安装好了Unity 2019或更高版本(NGUI其实支持到很老的版本,但建议用2019+,兼容性更好),并且已经导入了NGUI插件包。
1.1 导入NGUI
首先,你需要一个NGUI的资源包。你可以从Asset Store下载最新版(虽然更新慢,但稳定性好),或者使用GitHub上的开源镜像。导入过程很简单:
- 打开Unity
- 菜单栏选择
Assets > Import Package > Custom Package - 选择你下载的NGUI的
.unitypackage文件 - 点击导入,等待完成
导入后,你会看到Project视图里多了一个名为“NGUI”的文件夹。里面包含了所有的脚本、预制体、示例场景等。
1.2 理解NGUI的坐标系统
这是新手最容易踩坑的地方。UGUI使用Canvas和Rect Transform,而NGUI使用Widget和Screen Space / World Space两种模式。
- Screen Space:UI元素直接绑定到屏幕坐标,适合2D游戏或固定分辨率的界面。
- World Space:UI元素存在于3D世界中,适合3D游戏中的浮动文字、血条等。
你可以通过NGUI的 Widget 组件来设置这些属性。记住,NGUI的坐标原点是左下角,而不是UGUI的中心点。这个细节在很多老代码里会引发奇怪的偏移问题。
1.3 创建第一个NGUI界面
咱们来做个最简单的例子:一个带按钮的登录界面。
步骤一:创建UI Root
- 在Hierarchy视图中,右键选择
NGUI > Create New UI Root - 这会在场景中创建一个名为“UI Root”的GameObject,并附带
Camera和UI Root组件。 - 选中这个UI Root,在Inspector中设置
Camera的Projection为Orthographic(正交相机),Size设为10(这个值决定了你的世界单位大小,10意味着从底到顶是10个单位)。
步骤二:添加背景
- 右键UI Root,选择
NGUI > Create Empty - 命名为“Background”
- 添加
Box Widget组件(或者直接用Atlas下的精灵) - 设置Position为(0,0,0),Width为1920,Height为1080(假设你的目标是1080p)
- 给Background添加一个颜色或贴图,让它看起来像个背景。
步骤三:添加按钮
- 右键UI Root,选择
NGUI > Create Button - 这会自动创建一个包含
UIButton、UISprite和UILabel的层级结构。 - 调整按钮的位置,比如放在屏幕中央:Position (0, 0, 0)
- 修改按钮的标签文字,双击“Label”对象,输入“登录”
- 你可以调整按钮的大小、颜色、字体等。
这时候,你在Game视图中运行,应该能看到一个带有“登录”按钮的界面了。
第二步:深入NGUI的核心组件
光会创建界面还不够,你得理解每个组件的作用,这样才能灵活应对各种需求。
2.1 Widget:所有UI的基石
Widget是NGUI中最基础的组件,它定义了UI元素的边界、锚点和渲染顺序。每个UI对象几乎都必须有Widget。
关键属性:
- Pixel Offset:相对于锚点的像素偏移。
- Anchor:锚点设置,决定Widget如何相对于父对象定位。
- Depth:深度值,数值越大渲染顺序越靠前(类似Z-order)。
2.2 Button与Event Trigger
NGUI的按钮系统非常强大。除了基本的UIButton,还有UIButtonColor(鼠标悬停变色)、UIButtonSound(点击播放声音)等。
但更重要的是事件系统。NGUI使用的是EventTrigger,它是一个组件,可以监听各种UI事件,比如:
OnClickOnHoverOnPressOnReleaseOnDrag
你可以将这些事件绑定到任意脚本方法上。例如,创建一个脚本:
using UnityEngine;
public class LoginButtonHandler : MonoBehaviour
{
public void OnLoginClick()
{
Debug.Log("登录按钮被点击了!");
// 这里可以写你的登录逻辑
}
}
然后,在Button的EventTrigger组件中,找到OnClick事件,拖拽你的Button对象到这个槽位,选择方法LoginButtonHandler > OnLoginClick。
2.3 Label与字体
NGUI的Label用于显示文本。它支持多种字体格式,最常用的是.ttf或.otf真字体,以及NGUI特有的BMFont格式(位图字体)。
位图字体的优势是性能极佳,尤其是在移动设备上。你可以使用NGUI自带的工具将真字体转换为位图字体:
- 选中你的
.ttf字体文件 - 菜单栏选择
NGUI > Create > Font - 设置字符集、大小等参数
- 点击创建,NGUI会自动生成对应的位图资源
然后,在Label组件中选择这个生成的Font。
2.4 Tween与动画
NGUI内置了简单的动画系统,叫做Tween。它包含多种类型:
UITweener:基础动画器UITweenAlpha:透明度变化UITweenHeight:高度变化UITweenPosition:位置移动UITweenScale:缩放
你可以通过代码或Inspector来设置动画。例如,让按钮在点击后淡入:
using UnityEngine;
public class ButtonFadeIn : MonoBehaviour
{
public UIWidget widget;
void OnClick()
{
UITweener tween = widget.GetComponent<UITweener>();
if (tween != null)
{
tween.enabled = true;
tween.PlayForward();
}
}
}
当然,复杂动画建议你用Unity Animator,但简单的Tween对于轻量级UI来说已经足够。
第三步:实战案例——搭建一个简单的游戏主页
光说不练假把式。咱们来做一个完整的游戏主页,包含:
- 背景图
- 游戏标题
- 开始游戏按钮
- 设置按钮
- 退出按钮
3.1 场景搭建
按照前面的步骤,创建UI Root和背景。假设你有一张1920x1080的背景图,创建一个Sprite,命名为“Background”,大小设置为1920x1080,位置居中。
3.2 添加标题
- 右键UI Root,选择
NGUI > Create > Label - 命名为“Title”
- 设置文字为“我的超级游戏”
- 调整字体大小(比如72)、颜色(金色)、位置(屏幕上方居中)
- 可以添加一个简单的Tween动画,让标题缓缓淡入。
3.3 添加按钮组
- 复制“Title”下面的Label,创建三个按钮。
- 分别命名为“StartButton”、“SettingsButton”、“ExitButton”。
- 使用
UIButton预制体,或者手动创建包含Button、Sprite和Label的层级。 - 设置按钮的位置,比如垂直排列在屏幕中央。
- 为每个按钮添加
EventTrigger,绑定对应的方法。
3.4 编写交互逻辑
创建一个主脚本MainMenuController.cs:
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainMenuController : MonoBehaviour
{
public void StartGame()
{
Debug.Log("开始游戏");
SceneManager.LoadScene("GameScene");
}
public void OpenSettings()
{
Debug.Log("打开设置");
// 这里可以打开设置面板
}
public void ExitGame()
{
Debug.Log("退出游戏");
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}
然后,将这三个方法分别绑定到对应的按钮上。
3.5 添加音效
为了让界面更生动,你可以添加音效。使用UIPlaySound组件:
- 在场景中创建一个空对象,命名为“AudioSourceHolder”
- 添加
AudioSource组件 - 为每个按钮添加
UIButton组件,并在On Press事件中播放音效。 - 或者,直接在
EventTrigger中绑定播放音效的方法。
第四步:NGUI与UGUI的对比与选择
现在,你已经动手做了NGUI的界面,是不是感觉有点不一样?没错,NGUI更底层,你需要手动管理很多细节,但这也意味着你更清楚底层发生了什么。
那么,NGUI和UGUI到底该怎么选?
4.1 性能对比
- NGUI:在低端设备上性能略优,尤其是位图字体和Sprite合批方面做得很好。它的渲染逻辑更简单,适合对性能极其敏感的项目。
- UGUI:随着Unity版本的更新,UGUI的性能已经大幅提升,尤其是在UI动态刷新和复杂动画方面。但对于超大规模的UI列表(比如聊天框、背包),UGUI可能需要额外优化(如使用
RecyclerView类似的机制)。
4.2 开发效率
- NGUI:学习曲线较陡,文档相对陈旧,但一旦掌握,可以快速构建复杂界面。
- UGUI:学习曲线平缓,官方文档完善,社区资源丰富,快速原型开发首选。
4.3 兼容性与维护
- NGUI:不支持Unity的最新特性(如VR/AR中的UI),老项目维护成本低,但新项目如果选用NGUI,可能会遇到插件不再更新的问题。
- UGUI:原生支持Unity的所有新功能,跨平台兼容性更好,长期维护更有保障。
4.4 建议
- 如果你是新手,或者项目对性能要求不是极端苛刻,建议直接使用UGUI。它是未来的方向,社区活跃,遇到问题容易找到解决方案。
- 如果你正在维护老项目,或者项目对性能有极致要求(如超大规模移动游戏),NGUI仍然是一个可靠的选择。
- 如果你想去游戏公司面试,建议两个都懂一点。面试官可能会问:“你为什么选择NGUI而不是UGUI?” 或者 “UGUI的Canvas系统是如何工作的?”
第五步:常见问题与解决方案
在实际开发中,你可能会遇到一些NGUI特有的问题。我来列举几个最常见的,并给出解决方案。
5.1 按钮点击无响应
原因:可能是EventTrigger没有正确绑定,或者Widget的Interactive属性未勾选。
解决:检查Button对象的Widget组件,确保Interactive为true。然后检查EventTrigger中的事件是否绑定到了正确的脚本方法。
5.2 文字显示乱码或空白
原因:字体资源未正确生成,或者字符集不包含所需字符。
解决:重新生成BMFont,确保字符集包含所有需要的字符。检查Label的Font属性是否正确指向生成的字体资源。
5.3 UI层级混乱,被遮挡
原因:Widget的Depth属性设置不当。
解决:调整各个UI元素的Depth值,数值越大越靠前。或者,调整Hierarchy中的顺序(子对象在父对象之前渲染)。
5.4 不同分辨率下UI变形
原因:没有正确设置Camera的UI Scale Mode或Anchors。
解决:在UI Root的Camera组件中,设置UI Scale Mode为Scale With Screen Size,并设置Reference Resolution和Match Width or Height。同时,确保各个Widget的Anchor设置正确,以适应不同屏幕比例。
结语:选择适合你的工具
说了这么多,归根结底,NGUI和UGUI没有绝对的好坏,只有适不适合。NGUI像是一辆手动挡的赛车,你需要掌握它的每一个齿轮,但一旦熟练,它能带你飙出惊人的性能。UGUI则像是一辆自动挡的电动车,上手快,功能全,适合大多数日常通勤(开发)。
我见过很多开发者,只学过UGUI,然后遇到老项目就束手无策;也见过只懂NGUI的开发者,在面对新技术时显得有些吃力。所以,我的建议是:把NGUI当作一个理解UI底层原理的窗口,把UGUI当作日常开发的工具。这样,无论走到哪里,你都能游刃有余。
希望这篇文章能帮你理清思路。如果你在实践中遇到问题,欢迎随时来找我讨论。记住,UI开发是一门艺术,也是一门技术,慢慢来,你会越来越顺的。
