

[独立游戏框架2.0使用手册] 6.UI框架
CoParks
游戏开发从业人员/研究生已毕业
阅读 2634
2023年2月23日
UI框架的使用
UI框架
UI框架实现对窗口的生命周期管理,层级遮罩管理,按键物理响应等功能,对外提供窗口的打开、关闭、窗口复用API,对内优化好窗口的缓存、层级问题,能够和场景加载、事件系统联动,将Model、View、Controller完全解耦。通过与配置系统、脚本可视化合作,实现新UI窗口对象的快速开发和已有UI窗口的方便接入。
数据结构
虽然本文档使用手册,但为了便于上手理解,简单对UI框架的数据结构进行解释。
//UI窗口数据字典 Dictionary<string, UIWindowData> UIWindowDataDic; //UI窗口数据类 public class UIWindowData { [LabelText("是否需要缓存")] public bool isCache; [LabelText("预制体Path或AssetKey")] public string assetPath; [LabelText("UI层级")] public int layerNum; /// <summary> /// 这个元素的窗口对象 /// </summary> [LabelText("窗口实例")] public UI_WindowBase instance; public UIWindowData(bool isCache, string assetPath, int layerNum) { this.isCache = isCache; this.assetPath = assetPath; this.layerNum = layerNum; instance = null; } }
UI框架的核心在于维护字典UIWindowDataDic,通过windowKey索引了不同的UI窗口数据UiWindowData,其中包含了窗口是否要缓存,资源路径,UI层级,以及窗口类实例(脚本作为窗口对象的组件,持有他就相当于持有了窗口gameObject),UIWindowData可以通过运行时动态加载也可以在Editor时通过特性静态加载,设计windowKey的原因是如果不额外标定windowKey直接用资源路径作为索引,则同一个窗口资源无法复用,换句话说,同一个UI窗口游戏对象及窗口类,通过不同的windowKey和实例可以进行重用。
UI窗口对象及类配置
使用UI框架需要先为UI窗口游戏对象添加控制类,该类继承自UI_WindowBase,并将UI窗口游戏对象加入Addressable列表/Resources文件夹下。
UI窗口特性-Editor静态加载
可以选择为UI窗口类打上UIWindowData特性(Attribute可省略)用于配置数据。
UIWindowDataAttribute(string windowKey, bool isCache, string assetPath, int layerNum){} UIWindowDataAttribute(Type type,bool isCache, string assetPath, int layerNum){}
参数说明
- 特性中windowKey是UI窗口的名字唯一索引,可以直接传string也可以传Type使用其FullName。
- isCache指明UI窗口游戏对象是否需要缓存重用,true则在窗口关闭时不会被销毁,下次使用时可以通过windowKey调用切不需要实例化。
- assetPath是资源的路径,在Resources中是UI窗口对象在Resources文件夹下的路径,Addressable中是UI窗口对象的Addressable Name。
- layerNum是UI窗口对象的层级,从0开始,越大则约接近顶层。
- 支持一个窗口类多特性,复用同一份窗口类资源,n个特性,则有n份UI窗口数据,本质上对应了多个windowKey,因此windowKey必须不同。
经过配置后,在Editor模式下该UI类特性数据及UI窗口游戏对象(此时还没有实例化为空)会自动保存到GameRoot的配置文件中,即静态加载。
UI窗口运行时动态加载
在运行时动态加载UI窗口,不需要给窗口类打特性,窗口数据直接给出,与Onshow/OnClose不同,其不包含窗口游戏物体对象的显示/隐藏/销毁逻辑。
//API //(string windowKey, UIWindowData windowData, bool instantiateAtOnce = false) UISystem.AddUIWindowData(windowKey, windowData, instantiateAtOnce); UISystem.AddUIWindowData(windowKey, windowData, instantiateAtOnce); //(Type type, UIWindowData windowData, bool instantiateAtOnce = false) UISystem.AddUIWindowData(type, windowData, instantiateAtOnce); UISystem.AddUIWindowData(type, windowData); UISystem.AddUIWindowData<T>(windowData, instantiateAtOnce); UISystem.AddUIWindowData<T>(windowData); //简单实例 UISystem.AddUIWindowData("Test1", new UIWindowData(true, "TestWindow", 1)); //上一步只添加了数据,显示在面板上还需要激活 UISystem.Show<TestWindow>("Test1");
参数说明
- 通过泛型T指定UI窗口子类类型,windowKey为UI窗口类的索引,对应UIWindowData中的windowKey,不指定则使用T的类型名作为索引。
- instantiateAtOnce指明窗口对象及其类是否要进行实例化,默认为null,会在窗口打开时加载资源进行实例化且设置为不激活,若窗口资源较大,可以提前在动态加载时就进行实例化,如图。
UI窗口数据管理
获取UI窗口数据,其中包含UI的windowKey,层级,资源路径,以及对象实例,可以对其进行操作。
//获取UI窗口数据 //(string windowKey) (Type windowType) UISystem.GetUIWindowData(windowKey); UISystem.GetUIWindowData<T>(); UISystem.GetUIWindowData(windowType); //尝试获取UI窗口数据,返回bool //(string windowKey, out UIWindowData windowData UISystem.TryGetUIWindowData(windowKey, windowData); //移除某条UI窗口数据 //(string windowKey, bool destoryWidnow = false) UISystem.RemoveUIWindowData(windowKey, destoryWidnow); //清除所有UI窗口数据 UISystem.ClearUIWindowData(); //简单实例 //获取testWindow的层级 UISystem.GetUIWindowData<testWindow>().layerNum;
参数说明
- 通过windowKey/泛型类型名/窗口对象类型传索引。
- 支持Try方式获取窗口数据,成功返回true并将数据赋给输出参数。
- 移除UI窗口数据,已存在的窗口对象实例会被强行删除。
UI窗口对象管理
这里的UI窗口对象只UI窗口数据UIWIndowData持有的那一份窗口脚本对象实例,其生命周期由框架管理,整体分为打开和关闭。
UI窗口打开
加载UI窗口对象并显示。
//API //返回值为UI窗口类T,T受泛型约束必须为UI窗口基类子类 //(string windowKey, int layer = -1) UISystem.Show<T>(windowKey, layer); UISystem.Show<T>(windowKey); UISystem.Show<T>(layer); UISystem.Show<T>(); //返回值为UI_WindowBase类,对应不能确定窗口类型的情况, xx是窗口类的对象 //(Type type, int layer = -1) UISystem.Show(xx.getType(), layer); UISystem.Show(xx.getType()); //(string windowKey, int layer = -1) UISystem.Show(windowKey, layer); UISystem.Show(windowKey); //简单实例,打开窗口UI_WindowTest并置于第三层 UISystem.Show<UI_WindowTest>(2);
参数说明
- 通过泛型T指定UI窗口子类类型,windowKey为UI窗口类的索引,对应UIWindowData中的windowKey,不指定则使用T的类型名作为索引,layer代表UI的层级,不填则默认-1表示使用数据中原有的层级(通过静态配置或者动态加载指定)。
- 在明确UI窗口类型的时候可以直接通过泛型T指定,不明确则可以通过传对象反射来获取类型。
- 简单解释逻辑为根据windowKey找到对应的窗口数据UIWindowData,根据数据中的assetPath加载UI窗口对象并根据T返回窗口类,无T则返回UI_WindowBase类。
由于UI窗口类继承了UIWIndowBase,其中提供了一些可供重写的方法,这些方法会在UI窗口打开时自动执行。
//初始化相关方法,只有在窗口第一次打开时执行 public override void Init() { base.Init(); } //窗口每次打开时执行,可用于数初始化,并会自动调用事件监听注册方法 public override void OnShow() { base.OnShow(); } //事件监听注册 protected override void RegisterEventListener() { base.RegisterEventListener(); }
UI窗口关闭
//API //(Type type) (string windowKey) UISystem.Close<T>(); UISystem.Close(type); UISystem.Close(windowKey); UISystem.CloseAllWindow(); //简单实例,关闭窗口UI_WindowTest UISystem.Close<UI_WindowTest>();
参数说明
- 相比打开,关闭不需要返回值也不需要管理层级,通过T/Type/windowKey传入窗口的索引即可。
由于UI窗口类继承了UIWIndowBase,其中提供了一些可供重写的方法,这些方法会在UI窗口关闭时自动执行。
//窗口每次关闭时执行,会动调用事件监听注销犯法 public override void OnClose() { base.OnClose(); } //事件监听注销 protected override void RegisterEventListener() { base.RegisterEventListener(); }
获取/销毁UI窗口对象
获取/销毁UIWindowData持有的UI窗口对象实例,与Onshow/OnClose不同,其只获取实例,不包含窗口游戏物体对象的显示/隐藏/销毁逻辑。
//API //返回值为UI窗口类T,T受泛型约束必须为UI窗口基类子类 //(string windowKey) UISystem.GetWindow<T>(windowKey); UISystem.GetWindow<T>(Type windowType); UISystem.GetWindow<T>(); //返回值为UI_WindowBase类,对应不能确定窗口类型的情况 UISystem.GetWindow(windowKey); //返回值为bool,表示窗口对是否存在 //(string windowKey, out T window) UISystem.TryGetWindow(windowKey, window); //(string windowKey, out T window) UISystem.TryGetWindow<T>(windowKey, window); //销毁窗口对象 UISystem.DestroyWindow(windowKey); //简单实例,获取TestWindow上的UI Text组件Name Text name = UISystem.GetWindow<TestWindow>().Name;
参数说明
- 通过windowKey/type Name/T类型名查找窗口对象。
- 支持Try方式,查询成功则对象传递到输出参数out上,并返回bool为true,否则输出参数为null并返回false。
- 销毁窗口对象API会直接会游戏内的窗口gameObject、控制类,但UIWindowData还存在。
UI层级管理
框架内部实现了对UI的层架管理,可以在面板的UISystem上每一层是否启用遮罩,默认每一层UI是层层堆叠覆盖的,一旦某一层中有UI窗口对象,则层级比它低的层级都不可以交互,同一层级中比它早打开的UI窗口不可以交互(保证每一层内最顶层只有一个窗口),可以勾选不启用遮罩,则这一层层内和层外都不存在遮罩关系。
启用遮罩如下图。
Mask保证了每一层内最顶层只有一个窗口进行交互。
另外框架单独提供了最顶层dragLayer,用于拖拽时临时需要把某个UI窗口置于最上层,可以通过UISystem.dragLayer获取。
UISystem.dragLayer;
UI Tips
弹窗工具。
//API // 在窗口右下角弹出字符串tips提醒。 //(string tips) UISystem.AddTips(tips)
发布于技术交流
1条评论

问
AI
全新AI功能上线
1. 基于Unity微调:专为Unity优化,提供精准高效的支持。
2. 深度集成:内置于团结引擎,随时查阅与学习。
3. 多功能支持:全面解决技术问题与学习需求。

问
AI