deVoid UI Framework 架构设计解析:一条铁律如何拯救你混乱的 UI 代码
deVoid UI Framework 架构设计解析:一条铁律如何拯救你混乱的 UI 代码
【免费下载链接】uiframeworkThe deVoid UI Framework for Unity项目地址: https://gitcode.com/gh_mirrors/uif/uiframework
做 Unity 游戏的人都懂那种痛:HUD 挡在弹窗上、弹窗又挡住了主菜单,屏幕之间互相持有引用,改一个界面要翻半天代码。deVoid UI Framework(简称 devUI)是一个专为 Unity 设计的 UI 架构与导航框架,它用一条铁律和分层结构,帮你把混乱的 UI 代码整理得井井有条。本文带你从架构设计视角,快速看懂它为什么能让 Unity UI 架构变得简单、清晰、可扩展。
一条铁律:外部代码永远不许直接碰 UI 内部
整个框架的地基只有一句话:
外部代码永远不能直接访问 UI 的内部实现,一切交互都必须通过统一入口。
这条铁律的落点就是UIFrame—— 整个框架的中心访问点。所有"打开窗口、显示面板、注册屏幕"的调用都指向它,它再向内部分层转发:
uiFrame.RegisterScreen("YourScreenId", yourScreenPrefab); uiFrame.OpenWindow("YourWindowId"); uiFrame.ShowPanel("YourPanelId");好处立竿见影:
- ✅ 业务逻辑与 UI 实现彻底解耦,UI 重构不影响玩法代码
- ✅ 想读单例数据、上 MVC 或 MVVM 都行,框架不干涉你 UI 内部怎么写
- ✅ 每个 UIFrame 都是自包含结构,甚至可以在同场景并存多个 UI(分屏玩家专属 UI 就是这么实现的)
这条铁律的入口类见 UIFrame.cs。
四层架构:UI Frame → Layer → Screen → Widget
devUI 的层级结构非常克制,一层套一层,职责单一:
| 层级 | 职责 | 对应源码 |
|---|---|---|
| UI Frame | 唯一对外入口(门面模式) | UIFrame.cs |
| UI Layer | 管理某一类屏幕:注册、显示、隐藏 | Core/AUILayer.cs |
| Screen | 具体界面:Panel 或 Window | Core/AUIScreenController.cs |
| Widget | 屏幕内可复用的自包含小组件 | MANUAL 说明 |
屏幕如何被"注册"才能使用
这是框架的第二个关键约束:任何屏幕必须注册到某个 Layer 后才能被显示。注册时框架会自动把屏幕的 Transform 重新挂载(reparent)到正确的图层下,层级顺序从此不用你操心。注册逻辑见 Core/AUILayer.cs。
Panel 和 Window:两种屏幕各司其职
这是新手最容易困惑的点,也是框架最值得学的地方——它把屏幕明确分成两类:
🪟 Window(窗口):有历史、有队列,一次只能操作一个
- 占满屏幕大部分区域,是当前的主交互点
- 内置历史栈(Stack)和队列(Queue):打开新窗口自动压栈,关闭后回退到上一个
- 标记为Pop-up的窗口会自动置顶并加上暗色背景,天然的模态弹窗方案
实现见 Window/WindowUILayer.cs,其中windowQueue、windowHistory两个数据结构就是导航能力的核心。
📋 Panel(面板):随手开关的碎片 UI
- HUD、血条、小地图这类"想显示就显示"的 UI
- 无历史、无队列,可以和多个其他 Panel 同时可见
- 支持按Priority(优先级)挂到不同 Para-Layer,控制"谁画在谁前面"
实现见 Panel/PanelUILayer.cs。
💡 默认渲染顺序:PanelLayer → WindowLayer → PriorityPanelLayer → Pop-up 层 → 其他 Panel 层。
过渡动画与输入拦截:移动端 UI 的救命设计
每个屏幕都内置AnimIn/AnimOut两个过渡插槽,可挂载任意ATransitionComponent(见 ScreenTransitions/ATransitionComponent.cs),不挂则直接 SetActive,框架也自带简单的淡入淡出实现(ScreenTransitions/SimpleFadeTransition.cs)。
更贴心的是:移动端最常见的 bug 是"转场动画还没播完,用户就点了下一个按钮"。WindowUILayer检测到有过渡动画在播时,会自动禁用 GraphicRaycaster 拦截一切用户输入,动画结束自动恢复。相关逻辑见 Window/WindowUILayer.cs 与 UIFrame.cs。
5 分钟上手:三步跑通 devUI
第 1 步:在 Project 面板右键Create → deVoid UI → UIFrame Prefab,把 Prefab 拖进场景。
第 2 步:注册你的屏幕(每个屏幕用唯一 ScreenId,习惯上直接用 Prefab 名)。
第 3 步:调用OpenWindow/ShowPanel显示屏幕。
如果嫌代码注册麻烦,用内置的UI Settings一键配置(Create → deVoid UI → UI Settings):把 UIFrame Prefab 配成 UI Template,把所有屏幕拖进注册列表,之后一行代码拿到完整初始化的实例,自动注册全部搞定:
uiFrame = yourUiSettings.CreateUIInstance();配置类源码:UISettings.cs。
如何自定义你的屏幕:类型安全的 Properties 传参
屏幕的数据传递走"Properties 负载"机制,类型安全是框架明确的设计目标:
- 继承
AWindowController<TProps>或APanelController<TProps> - 重写
OnPropertiesSet()—— 这是填充数据的最佳入口,此刻Properties保证可用 - 事件监听统一放在
AddListeners()/RemoveListeners()中
public class PlayerWindowController : AWindowController<PlayerWindowProperties> { protected override void OnPropertiesSet() { UpdateData(Properties.PlayerData); // 拿到 OpenWindow() 传入的数据 } }两个实战细节值得注意:
- Properties 类必须加
[System.Serializable],否则无法在 Prefab 上配置 - 不给屏幕传参时,框架会回退到Prefab 上预设的属性值,编辑器就能预览默认状态
完整的方法生命周期清单(WhileHiding、Close()等)见手册 MANUAL.md。
这套架构解决了什么、又放弃了什么
devUI 的取舍非常清醒:它不强制MVC、不内置 MVVM、甚至不做手柄导航——框架只锁死"统一入口 + 分层隔离"这一件事,其余全部放行。这是作者在多款移动端 F2P 游戏里打磨出的最小公约数,也解释了为什么它"简单到三步上手"却撑得住中大项目的复杂度。
📚 延伸阅读:项目说明 README.md、官方手册 MANUAL.md
总结:一条铁律带来的秩序
- 🔒 一切调用走
UIFrame入口,UI 内部实现对外封闭 - 🧱 Frame / Layer / Screen / Widget 四层结构,职责清晰
- 🪟📋 Window 管历史与队列,Panel 管碎片 UI,Pop-up 天然模态
- 🎬 过渡动画可插拔,转场期间自动锁输入
- 📦 类型安全的 Properties 传参 + UI Settings 一键初始化
如果你正在被 Unity UI 的层级混乱和屏幕引用纠缠困扰,这套架构值得作为你下一个项目的起点。
【免费下载链接】uiframeworkThe deVoid UI Framework for Unity项目地址: https://gitcode.com/gh_mirrors/uif/uiframework
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
