UI 系统概述
Fink Framework 的 UI 系统是一套适用于 Unity(支持 VR / 非 VR)的完整 UI 管理框架。 新版 UI 系统经过架构级重写,引入了 多 Canvas 注册系统、面板缓存体系、三模式面板加载能力、自动化控件发现与事件绑定、VR WorldSpace 支持、资源 Provider 加载体系,能够满足中大型项目的 UI 架构需求。
1. 设计目标
新版 UI 系统旨在解决 Unity UI 开发中的常见问题:
- 多个 UI 面板缺乏统一管理
- VR 与非 VR 项目 UI 架构不一致
- UI 生命周期混乱(初始化、显示、隐藏、销毁)
- 控件事件需手动绑定,易遗漏
- 画布与 UI Camera / EventSystem 初始化繁杂
- WorldSpace UI 难以管理多个挂载点
- 缺乏异步加载能力,不适合 AB 包或远程 UI
为此,系统实现:
- 统一入口 UIManager
- 自动创建 UI Camera / EventSystem(支持 NewInput/XR/Oculus)
- 同步 / 异步 / 句柄 3 套面板加载模式
- 自动控件扫描与事件自动绑定(BasePanel)
- CanvasManager 注册多个 WorldSpace Canvas
- VR HUD / HandMenu / WorldPanel 全支持
- 面板缓存与等待加载机制(防止重复加载)
2. 总体架构
UI 系统由三大核心模块组成:
UIManager —— 顶层调度:加载、显示、隐藏、销毁面板
CanvasManager —— 多画布注册系统(VR 专用)
BasePanel —— 控件扫描与生命周期系统
以及三个辅助模块:
PanelInfo<T> —— 面板缓存结构
UIOperation<T> —— 异步句柄
CanvasRoot —— 在场景中声明可被管理的 Canvas
3. UIManager(核心调度器)
UIManager 是整个 UI 系统的入口,负责:
- 初始化 UI Camera(非 VR)
- 初始化 MainCanvas
- 初始化 EventSystem(老输入 / 新输入 / XR)
- 加载 UI 面板(同步 / 异步 / Handle)
- 管理 UI 层级(Bottom / Middle / Top / System)
- 将面板放到正确的 Canvas(HUD / HandMenu / WorldPanel)
- 缓存已加载面板(面板 Key = Scene + CanvasId + 面板名)
- 统一生命周期派发:
ShowMe() —— 首次创建调用一次
OnShow() —— 每次显示
HideMe() —— 首次隐藏调用一次
OnHide() —— 每次隐藏
OnDestroyPanel() —— 真正销毁前
面板加载方式
1) 同步加载
UIManager.Instance.ShowPanel<TestPanel>();
2) 异步加载(await)
var panel = await UIManager.Instance.ShowPanelAsync<TestPanel>();
3) 异步句柄(可查询进度)
var handle = UIManager.Instance.LoadPanelHandle<TestPanel>();
await handle.WaitUntilDone();
4. 多 Canvas 系统
用于管理 VR 项目的多画布结构。
CanvasRoot 场景组件定义:
- rootType(HUD / HandMenu / WorldPanel)
- canvasId(同类型下唯一)
- panelParent(面板挂载点)
CanvasManager 会:
- 自动扫描场景中所有 CanvasRoot
- 生成唯一 Key:SceneName + "_" + CanvasId
- 允许 UIManager 根据 rootType + canvasId 定位挂载点
- 自动为 WorldSpace Canvas 绑定 UI Camera / XR Raycaster
5. 自动控件扫描与 UI 生命周期
BasePanel 自动递归扫描常见 UI 控件:
Button、Toggle、Slider、InputField / TMP_InputField、Text / TMP_Text、Image、LayoutGroup / ScrollRect / Dropdown等…
扫描后会自动加入 controlDic 字典,并绑定事件:
ClickBtn(name)
ToggleValueChange(name, value)
SliderValueChange(name, value)
InputValueChange(name, value)
生命周期
ShowMe() —— 首次创建
HideMe() —— 首次隐藏
OnShow() —— 每次显示
OnHide() —— 每次隐藏
OnDestroyPanel() —— 面板被销毁
开发者只需继承 BasePanel 即可拥有完整流程:
public class TestPanel : BasePanel
{
public override void ShowMe() { }
public override void HideMe() { }
public override void OnShow() { }
public override void OnHide() { }
}
6. 面板加载流程(完整逻辑)
显示面板
1. 生成 Key(Scene + CanvasId + 面板名)
2. 若缓存中存在:
a. 若正在异步加载 → 等待
b. 若已加载 → 直接显示
3. 若不存在:
a. 在字典中占位(PanelInfo)
b. 加载 prefab(同步或异步)
c. 若异步中被隐藏 → 中断
d. 实例化 prefab
e. 调用生命周期 ShowMe / OnShow
隐藏面板
1. 如果在加载中 → 标记 isHide = true
2. 如果已加载:
a. 调用 HideMe
b. 调用 OnHide
c. isDestroy = true → 调用 OnDestroyPanel 并 Destroy()
7. VR 支持(WorldSpace UI)
新版 UI 系统完全支持 VR:
- 自动选择 XR EventSystem
- WorldSpace Canvas 自动挂 XR Raycaster
- WorldSpace Canvas 自动绑定 UI Camera(如果需要)
支持三种挂载根:
- HUD(头显)
- HandMenu(手部菜单)
- WorldPanel(固定位置 UI)
在 VR 项目中挂载方式:
await UIManager.Instance.ShowPanelMultiCanvasAsync<TestPanel>(
uiRootType: E_UIRoot.HandMenu,
canvasId: "LeftHand"
);
8. 自动 UI 面板生成工具
UIBuilderWindow 能自动完成:
- 生成 Panel 脚本文件(基于模板)
- 生成 Panel 预制体
- 自动创建示例控件(Button/Toggle/Input/Slider)
- 自动挂载脚本
- 自动设置背景与布局
- 生成 TMP 或 Legacy UGUI 两种版本
只需输入:
PanelName
PrefabPath
ScriptPath
是否添加示例控件
即可自动生成一个可用 UI 面板。
9. 核心优势(Why This System)
- 支持 VR / 非 VR 项目,全流程自动化
- 强解耦:控件无需手动拖引用
- 同步 / 异步 / Handle 三套 API,满足各种资源环境
- 自动管理多场景、多 Canvas(含世界空间)
- 自动控件扫描与事件绑定,减少 70% UI 代码
- 生命周期清晰,可维护性极高
- 能与 ResManager Provider 无缝结合,支持 AB / Remote
- 新版 UI 系统已经足够稳定,可作为中大型 Unity 项目的 UI 基础设施。