ZMUI
框架介绍
ZMUI框架是一款Mono分离式,高性能、自动化、商业级UI框架。
1.框架特点:
- 完全脱离MonoBehaviour的生命周期控制,自定义窗口弹出管线中的任意生命周期。
- 采用内存映射的方式设计框架,自动完成脚本和对象的关联绑定。
- 所有脚本、生命周期、组件字段声明、组件查找代码、组件绑定操作、组件事件绑定、组件方法声明等,全由ZMUI框架自动化系统完成,开发者无需编写反复无聊的作业,一键完成。
- 框架具有卓越的性能表现,框架从设计层,优化每一处影响性能的细节,把性能问题,扼杀在摇篮之中。
- 框架采用V+D的方式分离交互逻辑和组件持有脚本,使得交互脚本代码更加简洁、舒适、单一。V即View脚本,D即数据组件脚本。
- 框架属于MVC中的V,纯View框架,能够轻松接入替换自己项目的MVC,若需游戏代码架构,轻移至ZMGC....
2.框架提供成熟稳定的功能系统:
Mono分离式UI管理系统
脱离Mono的分离式架构,以内存映射的超级设计方式设计框架,彻底解决窗口生命周期不受自己控制的问题,窗口从生成到销毁所有接口流程全部掌握在自己手中,可自定义任何阶段生命周期接口。(窗口可以不挂载任何脚本的情况,正常执行弹窗的弹出、销毁、以及生命周期的调用
堆栈系统
成熟的堆栈管理。首页堆栈弹出、顺序控制、半路压入等,兼容各种情况,全局任意地方皆可使用
遮罩系统
完善遮罩的处理。提供单遮、叠遮模式两种模式,无缝切换
层级系统
负责框架中UI的层级管理,清晰透明, 解决UI叠加,特效模型穿插问题
高性能系统
负责Untiy UGUI相关极致的性能优化,彻底解决UI卡顿、不流畅的问题
自动化系统
提供自动生成组件查找代码、组件自动拖拽赋值绑定、字段自动生成、方法自动声明、事件接口声明、UI组件事件绑定、脚本生成等一条龙服务
高效率系统
提供预制体管理系统,预制体模板拖拽、Editor编译器、Editor针对框架特殊优化、提升开发效率
1.快速入门
1.1 获得ZMUI框架
ZMUI目前是以Git库为长期维护地址的
Example
1.2 初始化UI框架
注意:请在使用 UIModule 中的任何接口前调用。 public void Initialize()
{
mUICamera = GameObject.Find("UICamera").GetComponent<Camera>();
mUIRoot = GameObject.Find("UIRoot").transform;
mWindowConfig = Resources.Load<WindowConfig>("WindowConfig");
//在手机上不会触发调用
#if UNITY_EDITOR
mWindowConfig.GeneratorWindowConfig();
#endif
}
初始化接口前置条件
在调用初始化接口前要保证场景中存在UICamera和UIRoot节点。当然,你也可以对这些节点进行重命名。 但要保证,框架初始化时能够准确寻找到对应节点。
1.3 核心配置
下图配置窗口可以通过Unity引擎顶部菜单栏 : ZMFrame/ZMUI Setting 按钮呼出。
| 在该配置窗口中,你可以自定义: |
|---|
| 1.窗口遮罩模式 |
| 2.组件解析方式 |
| 3.代码生成方式 |
| 4.脚本自动化生成路径 |
| 5.窗口预制体存放路径 |
如果你只是想要简单、快速的使用,只需要配置 "5.窗口预制体存放路径" 即可。
注意
在弹出窗口时一定要指定工程内"窗口Prefab存放路径",框架会自动根据窗口Prefab存放路径文件夹,计算每一个窗口的加载路径。否则在弹出弹窗时,框架会找不到对应的窗口加载路径,导致窗口加载失败。
配置完成
初始化步骤和核心配置步骤完成之后,就可以正常使用UI框架进行窗口弹出了。
2.功能使用
2.1 窗口创建流程
1.框架提供了窗口模板供开发者进行使用。
模板路径: Assets\ZMPackages\ZMUI\Resources\Temp\TempWindow.prefab
2.使用方式:
在模板的基础上搭建界面,并修改模板窗口名称,制作成一个新的窗口即可。
3.节点介绍:
UIMask:窗口统一的遮罩层。
UIContent:窗口动画缩放节点,也是UI组件存放的父节点,若某节点不想参加窗口缩放动画,可移至与UIContent同级存放。
2.2 窗口脚本自动生成流程
1.ZMUI框架提供了自动化脚本生成工具。
以1.3配置窗口默认配置为例:
1.在场景中选中TempWindow窗口节点
2.Shift+B:生成 TempWindowDataComponent 组件绑定脚本。(该脚本只用来存储窗口组件,再次生成会重新覆盖)。
3.Shift+V:生成 TeampWindow 窗口交互脚本。(该脚本用来编写UI交互逻辑,再次生成会以递增的形式追加代码,不会覆盖原有代码)。
注意
在按下 Shift+B 生成脚本完成后,会出现报错,这个报错是找到不到组件监听的事件,故再次执行操作 3 把对用的组件事件方法生成即可解决报错。
所以在生成代码时,要按照上述 2 3 流程进行操作,因为操作 3 需要依赖 操作 2 产生的数据,他们是一套流水线,万不可跳过。
2.3 窗口使用API
ZMUI框架中,所有的窗口操作都在 UIModule 脚本中,下面给大家列一下常用的接口。
窗口弹出
public void Example()
{
//弹出窗口时需要通过泛型指定要弹出的窗口
UIModule.Instance.PopUpWindow<T>();
//例:1
UIModule.Instance.PopUpWindow<HallWindow>();
//例:2
HallWindow window = UIModule.Instance.PopUpWindow<HallWindow>();
window.OnExampleButtonClick();
}
窗口隐藏
public void Example()
{
//隐藏窗口框架提供2个重载接口
UIModule.Instance.HideWindow<T>();
//例:1
UIModule.Instance.HideWindow<HallWindow>();
//例:2
UIModule.Instance.HideWindow("HallWindow");
}
窗口获取
public void Example()
{
//如果你想要获取某一个已经显示的窗口,可以这样做
UIModule.Instance.GetWindow<T>();
//例:1
UIModule.Instance.GetWindow<HallWindow>().OnExampleButtonClick();
//例:2
HallWindow window = UIModule.Instance.GetWindow<HallWindow>();
window.OnExampleButtonClick();
}
窗口销毁
public void Example()
{
//如果你想要销毁指定窗口,可以这样做
UIModule.Instance.DestroyWindow<T>();
//例:1
UIModule.Instance.DestroyWindow<HallWindow>();
//如果你想要销毁所有窗口,可以这样做
//例:2
UIModule.Instance.DestroyAllWindow();
//例:3 过滤的销毁窗口列表
List<string> filterWindow = new List<string> { "HallWindow" };
UIModule.Instance.DestroyAllWindow(filterWindow);
}
窗口压栈
public void Example()
{
//1.如果你想要在压栈的同时立即弹出栈内的弹窗,可以这样做
UIModule.Instance.PushAndPopStackWindow<HallWindow>();
//2.如果你只想简单压栈一个弹窗,并不进行弹出,可以这样做
UIModule.Instance.PushWindowToStack<HallWindow>();
//3.如果你想要栈内的弹窗主动弹出,可以这样做
UIModule.Instance.StartPopFirstStackWindow();
}
3.系统介绍
3.1 遮罩系统
1
3.2 层级系统
1.ZMUI框架对层级的设计和定义如下:
- 一级窗口 Order in Lyaer 渲染层级为 0-99 区间 (一级窗口相当于各个场景的主页面,如登录页,大厅主页,战斗主页窗口)
- 二级窗口 Order in Lyaer 渲染层级为 100-199 区间 (二级窗口则是点击一级窗口上的按钮弹出的会覆盖在一级窗口上的其他窗口,如商城、工会、背包、排行榜、个人信息页面等)
- 三级窗口 Order in Lyaer 渲染层级为 200-299 区间 (三级窗口的定义 则是点击二级窗口上的按钮弹出的会覆盖在二级窗口上的其他窗口,如商城确认购买弹窗、背包确认使用或确认删除弹窗等)
- 以此类推,具体需要几级,根据项目的重度去决定。但一级和二级的窗口定义,不可更改,否则在使用本框架时会影响体验性,增加后续窗口之间交互时层级问题。
每一个都窗口在制作完成后都会有一个概念,他是属于哪种窗口,根据不同层级的窗口去划分和设置窗口的层级。
2.框架采用OVC的设计方式,即一个窗口一个Canvas。
原因:
常见做法:UIRoot1 UIRoot2 UIRoot3 UIRoot4 , 每个Root节点下存放不同层级的窗口,这种做法至少也需要4-6个Canvas。
单独Canvas的做法:经过多个项目测试,最多同时显示的窗口也不会超过5个,基本在2-4左右,所以Canvas带来的缺点基本就可以不用担心了。
优点:
1.独立性:
- 每个 Canvas 是独立的,可以单独控制其渲染顺序、事件处理和层级。
- 可以更容易地启用或禁用某个特定窗口,而不会影响其他 UI 元素。
2.性能优化:
- 由于每个窗口都是独立的,故实现了窗口隔离,在A窗口进行重绘时并不会影响到B窗口,从而实现简单的动静分离提升性能。
- 可以对每个 Canvas 进行单独的优化,例如调整其 Render Mode 和 Pixel Perfect 设置。
- 窗口被重绘的原因是很多的,而独立的Canvas窗口能够做到单独的重绘,而相较于一个Canvas下存放多个窗口,若其中某一个窗口触发了重绘,就会导致整个Canvas下的所有元素进行重绘,该Canvas下的节点越多,性能压力越大。
- Canvas分离能最大化的减少网格重建带来的性能消耗
3.易于管理:
- 每个窗口有自己的 Canvas,可以在场景中更直观地看到和管理各个 UI 组件,和调整层级。
- 便于组织和维护代码,因为每个窗口的逻辑可以封装在一个单独的脚本中。
- 在处理窗口与窗口之间穿插特效、模型、这种设计方式能以及其简单的操作实现UI与模型和特效之间的穿插渲染。
4.灵活的布局:
- 可以更灵活地控制每个窗口的位置和大小,不受其他窗口的影响。
- 可以使用不同的 Canvas Scaler 设置来适应不同的屏幕尺寸和分辨率。
5.事件处理:
- 每个 Canvas 有自己的事件系统,可以独立处理输入事件,避免事件冲突。
- 可以更容易地实现复杂的交互逻辑,例如模态对话框。
缺点:
- Canvas带来DrawCall的原因是Canavs打断了合批,且不是同一个画布。会额外增加一个Drawcall。但场景中最大打开窗口基本不会超过5个,这个损耗与常用多窗口父节点的做法下相等。
注意
窗口层级管理系统能够 尽量的降低 窗口之间交互的层级问题、UI与特效与UI之间的穿插露馅、UI与模型与UI之间的遮挡的问题
所以尽量遵循此设计,否则你会增加在遇到复杂场景时的显示问题。
3.3 自动化系统
自动化西系统旨在为了解决日常开发中重复且繁琐的工作而设计的。 主要功能包括:
- 自动生成包含生命周期、组件事件函数的窗口脚本 (以递增的形式追加并生成最新代码,不会覆盖已编写逻辑)。
- 自动生成组件查找脚本。
- 自动生成组件绑定脚本。
- 自动挂在对应窗口。
- 自动生成组件字段。
- 自动生成组件事件监听代码。
- 自动拖拽组件进行引用持有。
- 自动计算窗口加载路径,新建窗口无需添加任何配置即可直接弹出使用。
1.自动化系统提供两套脚本生成方式,和两套组件解析方式。
脚本生成类型:
1.组件查找脚本 (生成基于Find查找代码的窗口交互脚本)
2.组件绑定脚本 (生成自动拖拽组件的窗口交互脚本,并对其字段进行拖拽赋值)
2.自动化系统提供两种窗口组件解析方式:
组件解析类型:
1.节点名称:
格式:需要以 [组件或脚本类名]+字段名称 的格式设置节点名称,如:[Button]Login 解析完成后会自动生成 Public Button LoginButton;字段
2.节点标签
格式:需要在节点的 Inspector 面板上的 Tag属性 设置节点需要解析哪个组件,代码在生成时会读取 Tag+节点名称 生成对应的字段。如:Login节点的Tag设置为Button ,解析完成后会自动生成 Public Button LoginButton; 字段。
}
3.5 高性能系统
进行动静分离拆分Canvas,把频繁移动的放到动态Canvas下,一方面可以降低静态元素的更新频率,另一方面可以减小重建时涉及到的Mesh大小(重建是以Canvas为单位进行的)
避免频繁的销毁合创建一个界面
避免频繁的SetActive界面,可以用CanvasGroup进行代替
尽可能的避免使用Unity自带的OutLine组件,该组件会使得文本的Mesh增加4倍,导致UI重建开销明显增大
尽可能的避免使用Unity自带的Shadow组件,该组件同样会使得Mesh增加顶点增多。
谨慎使用Text的Best Fit选项,代价很高,增加额外生成时间。(禁Best Fit)
Mask换Rect Mask 2D或者网上的Mask组件。mask以内和以外把UI分割成两个“世界”,依次计算两个“世界”的drawcall,然后再相加。所有能不用就不用。
避免Image Text 不需要RayCast Target的组件开启该功能,因为UGUI在手指点击的时候,其实是Cavas上挂的一个Graphic Raycaster组件去遍历整个Cavas下所有UI元素的RayCast Target属性是否允许点击,我们把不需要点击的组件勾掉,会节省不小的性能开销。
图集一定要规范,不要一个界面用很多图集中的图片, 影响drawcall数量的根本是batch(批处理数),而batch是根本一个一个图集来进行批处理的,如果相邻的两张Image不是一个图集,那么就会造成两个Batch。
图文交叉,比如 image1 image2 Text 这样的顺序下是两个Drawcall,如果换成 Image1 Text Imgae2 由于Text会打断合批,所以即使两个Image是同一个图集中的图片,也会产生3个Drawall。Unity2020以上版本对这种方式有优化,不会在打断,但非图集图片仍会
避免Text RichText 属性,当Text组件勾选了Rich Text的时候,其实每次文本显示或赋值时都会先判断一下是否拥有这个属性,然后做正则匹配。如果频繁赋值,也是一笔不小的开销。
无用的Image以及Sprite为空的Image会打断合批,要谨慎使用。
如果界面不显示了,该界面的一切周期函数比如Update一定要停掉
3.5 高效率系统
5
框架 Runtime API
UIModule 核心类
UIModule是ZMUI的窗口管理类,用来初始化UI框架,管理窗口的弹出、隐藏、销毁、创建、入栈、出栈、等一系列操作,是Runtime时的核心类。
Initialize
Initialize是初始化ZMUI框架的接口,他决定了整个UI框架是否可用,需要在程序启动时进行调用。
public void Initialize()
{
mUICamera = GameObject.Find("UICamera").GetComponent<Camera>();
mUIRoot = GameObject.Find("UIRoot").transform;
mWindowConfig = Resources.Load<WindowConfig>("WindowConfig");
//在手机上不会触发调用
#if UNITY_EDITOR
mWindowConfig.GeneratorWindowConfig();
#endif
}
初始化接口前置条件
在调用初始化接口前要保证场景中存在UICamera和UIRoot节点。当然,你也可以对这些节点进行重命名。 但要保证,框架初始化时能够准确寻找到对应节点。
PopUpWindow
void PopUpWindow < T > ( );
窗口弹出接口,通过框架生成的所有窗口,都可以使用此API进行窗口的弹出。
| 参数 | 作用 | ||
|---|---|---|---|
| 泛型T | 表示要弹出的窗口类型 |
示例
public void Example()
{
//例:1
UIModule.Instance.PopUpWindow<HallWindow>();
}
PreLoadWindow
T PreLoadWindow < T > ( );
窗口预加载接口,只加载物体,提升PopUpWindow时的性能和流畅度,不调用生命周期,但窗口依赖的资源会加载至内存中。
| 参数 | 作用 | ||
|---|---|---|---|
| 泛型T | 表示要预加载的窗口类型 |
| 返回值 | 描述 |
|---|---|
| T | 预加载成功:返回获取到的窗口脚本,与传入的泛型T相等。 预加载失败:返回 Null |
示例
public void Example()
{
//例:1
UIModule.Instance.PreLoadWindow<HallWindow>();
}
GetWindow
T GetWindow < T > ( );
获取已经显示的窗口,若窗口不在显示中,则返回Null。
| 参数 | 作用 | ||
|---|---|---|---|
| 泛型T | 表示要获取的窗口类型 |
| 返回值 | 描述 |
|---|---|
| T | 获取成功:返回获取到的窗口脚本,与传入的泛型T相等。 获取失败:返回 Null |
示例
public void Example()
{
//例:1
UIModule.Instance.GetWindow<HallWindow>().OnExampleButtonClick();
//例:2
HallWindow window = UIModule.Instance.GetWindow<HallWindow>();
window.OnExampleButtonClick();
}
HideWindow
void HideWindow < T > ( );
隐藏指定的窗口,若窗口显示中,则直接隐藏。若窗口不在显示中,则进行跳过,无异常。
注:框架的窗口隐藏和显示均是通过CanvasGroup实现,目的是为了降低通过SetActive隐藏触发的重绘造成的性能影响。
| 参数 | 作用 | ||
|---|---|---|---|
| 泛型T | 表示要隐藏的窗口类型 |
示例
public void Example()
{
//例:1
UIModule.Instance.HideWindow<HallWindow>();
}
DestroyWindow
void DestroyWindow < T > ( );
销毁指定的窗口,若窗口存在,则直接把窗口物体Destroy掉。若窗口不在显示中,则进行跳过,无异常。
| 参数 | 作用 | ||
|---|---|---|---|
| 泛型T | 表示要销毁的窗口类型 |
示例
public void Example()
{
//例:1
UIModule.Instance.DestroyWindow<HallWindow>();
}
DestroyAllWindow
void DestroyAllWindow(List
销毁所有窗口,包括显示中和隐藏中的窗口。
| 参数 | 作用 |
|---|---|
| filterlist | 表示在销毁的过程中要过滤掉哪些窗口,可以通过这个字段保留某些窗口不被销毁 |
示例
public void Example()
{
//例:1
UIModule.Instance.DestroyAllWindow();
//例:2 过滤的销毁窗口列表
List<string> filterWindow = new List<string> { "HallWindow" };
UIModule.Instance.DestroyAllWindow(filterWindow);
}
PushWindowToStack
void PushWindowToStack< T >(Action< WindowBase > popCallBack = null,bool allowRepeat=true,bool pushToStackTop = false) where T : WindowBase, new()
压栈一个窗口,并约束T只能为继承WindowBase的类,且可以通过New的方式主动创建出来。
| 参数 | 作用 |
|---|---|
| popCallBack | 堆栈中的弹窗出栈的回调,可在这个接口中根据返回的 WindowBase 进行强转为指定窗口脚本后,调用其接口 |
| allowRepeat | 同一个窗口若允许压栈多个,此字段设置为true,若只允许压栈一个,此字段设置为false |
| pushToStackTop | 某一个窗口如果想要进行插入操作直接压到栈顶,优先弹出,此字段设置为true。默认按先后顺序压到栈尾 |
示例
public void Example()
{
//压栈第一个窗口
UIModule.Instance.PushWindowToStack<LoginWindow>();
//压栈第二个窗口
UIModule.Instance.PushWindowToStack<HallWindow>((winBase) => {
//该窗口出栈显示时刻触发
HallWindow window = winBase as HallWindow;
window.OnAgentButtonClick();
},false,true);
//开始出栈
UIModule.Instance.StartPopFirstStackWindow();
}
StartPopFirstStackWindow
void StartPopFirstStackWindow()
开始弹出堆栈弹窗,若堆栈中有弹窗,则立即弹出。
PushAndPopStackWindow
void PushAndPopStackWindow< T >(Action
压栈并立即弹出栈内第一个压栈的弹窗,若期间该接口在次触发,则只做压栈处理。
| 参数 | 作用 |
|---|---|
| popCallBack | 堆栈中的弹窗出栈的回调,可在这个接口中根据返回的 WindowBase 进行强转为指定窗口脚本后,调用其接口 |
| allowRepeat | 同一个窗口若允许压栈多个,此字段设置为true,若只允许压栈一个,此字段设置为false |
| pushToStackTop | 某一个窗口如果想要进行插入操作直接压到栈顶,优先弹出,此字段设置为true。默认按先后顺序压到栈尾 |
示例
public void Example()
{
//压栈并立即弹出HallWindow
UIModule.Instance.PushAndPopStackWindow<HallWindow>((winBase) => {
//该窗口出栈显示时刻触发
HallWindow window = winBase as HallWindow;
window.OnAgentButtonClick();
},false,true);
//压栈第二个个窗口 这个窗口会在HallWindow关闭后自动弹出
UIModule.Instance.PushAndPopStackWindow<LoginWindow>();
}
PopNextStackWindow
void PopNextStackWindow(WindowBase windowBase)
内部方法:自动弹出栈内的下一个弹窗。
若当前弹窗是通过堆栈弹出的弹出,在关闭时会触发此接口。否则会执行跳过逻辑。
| 参数 | 作用 |
|---|---|
| windowBase | 当前关闭的窗口的基类 |
ClearStackWindows
void ClearStackWindows()
清理栈内所有待弹出的弹窗。
重要属性
bool mSmartShowHide = true;
智能显隐开关。 默认开启,建议开启,因为开启可以提升性能,而关闭和开启从表现上无区别。
若应用主打市场是中高端市场,可以选择关闭,关闭后在使用流程上则轻松很多。
智能显隐
智能显隐:主要用来优化窗口叠加时被遮挡的窗口参与渲染计算,导致帧率降低的问题。
显隐规则:由程序设定某个窗口是否为全屏窗口。(全屏窗口设定方式:在窗口的OnAwake接口中设定该窗口是否为全屏窗口如 FullScreenWindow=true)
1.智能隐藏:当FullScreenWindow=true的全屏窗口打开时,框架会自动通过伪隐藏的方式隐藏所有被当前全屏窗口遮挡住的窗口,避免这些看不到的窗口参与渲染运算, 从而提高性能。
2.智能显示:当FullScreenWindow=true的全屏窗口关闭时,框架会自动找到上一个伪隐藏的窗口把其设置为可见状态,若上一个窗口为非全屏窗口,框架则会找上上个窗口进行显示, 以此类推进行循环,直到找到全屏窗口则停止智能显示流程。
注意:通过智能显隐进行伪隐藏的窗口在逻辑上仍属于显示中的窗口,可以通过GetWindow获取到该窗口。但是在表现上该窗口为不可见窗口,故称之为伪隐藏。
智能显隐逻辑与(打开当前窗口时隐藏其他所有窗口相似)但本质上有非常大的区别,
1.通过智能显隐设置为不可见的窗口属于伪隐藏窗口,在逻辑上属于显示中的窗口。
2.通过智能显隐设置为不可见的窗口可以通过关闭当前窗口,自动恢复当前窗口之前的窗口的显示。
3.通过智能显隐设置为不可见的窗口不会触发UGUI重绘、不会参与渲染计算、不会影响帧率。
4.程序只需要通过FullScreenWindow=true在窗口OnAwake函数中指定哪些窗口为全屏窗口即可,智能显隐的所有逻辑均有框架自动维护处理。
FullScreenWindow=true 设置全屏窗口示例:
示例
WindowBase
WindowBase是框架中所有窗口的基类,所有窗口都会继承WindowBase。 WindowBase封装了一些窗口通用的函数和属性,提供最基础的服务。
具有明显且简单意义的接口和字段不会出现在此文档中。
属性相关
mDisableAnim
是否禁用动画,默认开启。 若禁用,窗口在弹出时则不会做对应的缩放动画表现。
InitializeBaseComponent
void InitializeBaseComponent()
初始化框架基础数据和组件的接口,在OnAwake中自动调用。
注意
该接口中会主动查询并获取UIMask和UIContent节点,要保证这个两个节点存在,框架模板自动支持,强烈建议使用框架模板进行制作窗口。
OnAwake
override void OnAwake()
窗口"首次显示"时调用的接口,与MonoBehaviour的Awake作用一致。
由框架内部自动调用,子类可重写实现。
OnShow
override void OnShow()
窗口"每次显示"时都会调用的接口,包含首次打开。与MonoBehaviour的OnEnable作用一致。
由框架内部自动调用,子类可重写实现。
另外在WindowBase中的OnShow接口中,会调用ShowAnimation做窗口打开的动画表现逻辑,如果你想修改窗口的弹出动画
可以在WindowBase中的ShowAnimation接口中修改原有逻辑,从而实现统一窗口表现动画。
OnUpdate
override void OnUpdate()
窗口"显示期间"每帧都会调用的接口,与MonoBehaviour的Update作用一致。
框架为保证性能,默认不实现此接口,如果需要使用,可在子类中进行写实现并在Awake中把Update字段设置为true。
OnHide
override void OnHide()
窗口"每次隐藏"时调用的接口,与MonoBehaviour的OnDisable作用一致。
由框架内部自动调用,子类可重写实现。
OnDestroy
override void OnDestroy()
窗口被"销毁"时调用的接口,与MonoBehaviour的OnDestroy作用一致。
由框架内部自动调用,子类可重写实现。
ShowAnimation
override void ShowAnimation()
窗口弹出时DoTween动画的表现逻辑。
由框架OnShow接口自动调用,若不需要可以移除调用或修改弹出逻辑。
HideAnimation
override void HideAnimation()
窗口隐藏时DoTween动画的表现逻辑。
由框架OnHide接口自动调用,若不需要可以移除调用或修改弹出逻辑。
SetVisible
override void SetVisible(bool isVisble)
窗口被框架设置为隐藏时触发的隐藏逻辑,非特殊情况下,不允许调用。
| 参数 | 作用 |
|---|---|
| isVisble | 表示窗口是否可见 |
SetMaskVisible
override void SetMaskVisible(bool isVisble)
窗口UIMask遮罩被框架设置为隐藏时触发的隐藏逻辑,非特殊情况下,不允许调用。 一般会随着窗口同时可见和不可见。
| 参数 | 作用 |
|---|---|
| isVisble | 表示UIMask遮罩是否可见 |
PseudoHidden
virtual void PseudoHidden(int value)
窗口伪隐藏时触发的函数。 当前窗口被其他全屏窗口完全遮挡住时,被遮挡住的窗口会进入伪隐藏来提升性能和帧率。
但需要在全屏弹窗OnAwake中设置FullScreenWindow=true,标记某个窗口是全屏窗口。
| 参数 | 作用 |
|---|---|
| value | 0:表示窗口被伪隐藏。1:表示窗口从伪隐藏中恢复正常显示。 |
示例
//FullScreenWindows 使用参考
public override void OnAwake()
{
FullScreenWindow = true;
mDisableAnim = true;
dataCompt = gameObject.GetComponent<HallWindowDataComponent>();
dataCompt.InitComponent(this);
base.OnAwake();
}
//PseudoHidden接口实现参考
public override void PseudoHidden(int value)
{
base.PseudoHidden(value);
}
AddButtonClickListener
void AddButtonClickListener(Button btn, UnityAction action)
窗口在首次弹出由框架统一添加按钮事件的函数,自动化系统会自动生成按钮事件和按钮事件监听代码,无需手动调用。
特殊情况若需要手动调用请参考example。
| 参数 | 作用 |
|---|---|
| btn | 表示是哪个按钮要添加事件 |
| action | 表示按钮添加的监听回调 |
AddToggleClickListener
void AddToggleClickListener(Toggle toggle, UnityAction
窗口在首次弹出由框架统一添加Toggle事件的函数,自动化系统会自动生成Toggle事件和Toggle事件监听代码,无需手动调用。
特殊情况若需要手动调用请参考example。
| 参数 | 作用 |
|---|---|
| btn | 表示是哪个Toggle要添加事件 |
| action | 表示Toggle添加的监听回调 |
AddInputFieldListener
void AddInputFieldListener(InputField input, UnityAction
窗口在首次弹出由框架统一添加InputField事件的函数,自动化系统会自动生成InputField事件和InputField事件监听代码,无需手动调用。
特殊情况若需要手动调用请参考example。
| 参数 | 作用 |
|---|---|
| input | 表示是哪个InputField要添加事件 |
| onChangeAction | 表示InputField添加的输入改变监听回调 |
| endAction | 表示InputField添加的输入结束监听回调 |
示例
RemoveAllButtonListener
void RemoveAllButtonListener()
移除所有已添加的按钮事件,窗口在销毁时由框架自动触发,无需手动调用。
RemoveAllToggleListener
void RemoveAllToggleListener()
移除所有已添加的Toggle事件,窗口在销毁时由框架自动触发,无需手动调用。
RemoveAllInputListener
void RemoveAllInputListener()
移除所有已添加的InputField事件,窗口在销毁时由框架自动触发,无需手动调用。
WindowConfig
脚本介绍
WindowConfig是框架中自动化计算所有窗口加载路径的配置类,它继承于"ScriptableObject",在计算的同时,还具备配置储存的功能。
主要的目的是为了实现窗口加载路径的自动化,彻底解决每创建一个窗口,就需要到某个配置文件中去配置一下窗口的名字和加载路径这个繁琐的工作。
注意
前提需要在Unity引擎顶部菜单栏 : ZMFrame/ZMUI Setting 配置预制体存放路径。
GeneratorWindowConfig
void GeneratorWindowConfig()
根据预制体储存位置,计算所有窗口基于Assets的加载路径。 如果你使用的是Resources加载方式,计算路径时需要进行修改为基于Resources的加载路径。
示例
注意
需要在初始框架时调用,且禁止在手机上进行调用,否则会产生性能消耗。
GetWindowData
WindowData GetWindowData(string wndName)
根据窗口的名称,获取窗口的加载路径。
| 参数 | 作用 |
|---|---|
| wndName | 窗口名称 |
