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 基础设施。