UIFrame
UI框架 方便解决的问题
- 游戏UI中出现多个窗口,窗口与窗口之间的模态关系
- 当出现多个窗口,上面的窗口是当前只能操作的窗口
- 下面的窗口是模态的,看不清的,也是不能操作的
- 经常需要找对象,找组件,找组件里的方法或属性【重复性非常高的体力活】
- 通过对所有模块对象的统一管理
- 组件的统一设置
- 事件的统一调配
- 本地化语言问题【中文/英文】
- 消息机制
管理UI窗口与模态处理
通过一个名字返回该名字所对应的窗口的预设体
- 定义:什么是窗口?
- 开发者自定义,可以是一个Panel管理或者是一个空对象管理
- 游戏的外观模式
- 游戏开始时,创建中只有几个基础的游戏对象
- 所有的内容,都是外观模式作为入口动态生成的
- 窗口的动态生成
- 所有窗口都是一个资源【预设体】
- 如何加载资源
- Resource.Load();【本地】
- AssetsBundle()【服务器】
- 所有资源都放在Resource文件夹下
- 资源缓存机制
- 第一次从Resource文件夹中加载资源
- 从第二次开始,从缓存中加载资源
- 资源缓存机制
- 如何加载资源
- 所有窗口都是一个资源【预设体】
- 关于所有资源的路径配置
- 不同的窗口,资源的路径时不一样的
- 就需要一个配置文件去统一管理所有窗口的资源路径
- 配置文件选择 XML/JSON
- Json也是一个文件,也需要加载
- 配置文件的路径—>可以使用系统常数类来管理
- Resource加载的类型【TextAssets】
- 通过单例模板,建立资源管理单例
- Json文件的解析
- LitJson/UnityJson库
- 解析后存储到内存
- 最终目的–>对外接口,通过一个名字返回该名字所对应的窗口的预设体
实现UI的模态处理
- 所有UI模块都有统一的基类组件:UIModuleBase,依赖于Canvas Group
- 非当前模块不能进行UI操作
- Canvas Group组件
- Blocks Raycasts
- True: 检测射线,从而触发事件,可以操作UI
- False:不检测射线,不能触发事件,不可以操作UI
- Blocks Raycasts
- Canvas Group组件
实现UI模块的状态管理
OnEnter进入状态 Canvas Group Blocks Ratcasts = true;
OnParse暂停状态 Canvas Group Blocks Ratcasts = false;
OnResume恢复状态 Canvas Group Blocks Ratcasts = true;
OnExit离开状态 Canvas Group Blocks Ratcasts = false;
整体UI模块栈管理
Stack<UIModuleBase>
PushUI(string panelName)
PopUI()
对模块中需要访问的对象,组件,组件的属性/方法进行封装
通过UIManager管理所有模块
Module
以及模块中的元件Widget
UIManger通过模块名称找到相应名称找到相应的模块
模块可以通过元件的名称找到相应的元件
管理示例
MainModule | TaskModule | SystemModule |
---|---|---|
TaskButton_F | GetRewardButton_F | ShutDownVoiceButton_F |
SystemButton_F |
所有可操作元件上自动添加脚本组件
UIWidgetBase
这样的管理结构为:
Dictionary<string,Dictionary<string,UIWidgetBase>>
每个模块去遍历所有有用的子对象【元件】
- 给每个元件添加脚本组件
UIWidgetBase
- 每个元件生成后,会自动注册到UIManager
- 给每个元件添加脚本组件
这样,就可以通过UIManager找到任意一个已经生成了的模块元件
每个UIWidget都可以实现UI的所有功能
- 创建各个组件的接口
- IText,IImage,IButton…
- 创建各个组件的接口
拿到任意一个UIWidget都可以使用里面封装好的方法
最终每个UIModule对应一个控制器,基类
UIControllerBase
- 每个控制器处理当前模块的业务逻辑【真正的框架使用】
本地化语言
语言管理类
LocalizationManager
- 简体中文,繁体中文,英文,日文,法文…
- 添加委托注册和取消委托注册方法的接口
- 更换语言方法
ChangeLanguage
,根据设置的语言,调用所有注册的SetText方法- 设置生成后,将语言ID存储在本地,持久存在
给支持本地化的Text,绑定组件
LocalizationText
- 需要做多语言的Text都添加该脚本组件
- 从Json配置文件中读取该文件的多语言内容string[]
- 在LocalizationManager中注册自己的SetText(语言ID)方法
具体细则
Scripts
- Facade
- GameFacade.cs
- UIFrame
- Managers
- UIManager.cs
建立管理UIModule和Widget的字典和管理Module的栈
Module GameObject:输入UIType使panel模块实例化在canvas中且返回模块
Module Stack:建立栈存储Module 且执行出栈入栈时的操作 UIPanelName->UIType->Module 提供公共的函数供外界使用
widget相关操作:
UI Widgets->Module (Un)Register:向字典中添加modules(第一个string)
UI Widgets Add/Remove:添加或删除widgets
Find Widget:找module中的widgets - UITypeManager.cs panelName获得UIType
- UIManager.cs
- Models
- JsonLocalizationModel.cs 把json的文本转换成class的loc模型
- JsonPanelsModel.cs 把json的文本转换成class的panel模型
- UIType.cs 储存panel数据的一个class 输入路径返回class 单个panel的模型
- UIBases
- UIControllerBase.cs 写模块中组件的逻辑的基类
- UIModuleBase.cs 实现panel模块的基类
- UIWidgetBase.cs 实现添加移除模块中组件的基类
- UIInterface
- …各种组件的接口 定义要实现的功能
- UIMono.cs 综合上诉接口实现功能的函数
- Utility
- AssetsManager.cs 输入路径返回物体 加载文件
- JsonDataManager.cs 解析json 先变为model再变为字典存储
- Singleton.cs 单例基类 子类私有构造
- SystemDefine.cs 常数类
- Managers
- UserLogic用于实现需求的
- UIControllers绑定不同panel上要实现的功能
- MainPanelController.cs
- …
- UIModules挂载在每个Penel的prefab上 实现进出动画等
- MainPanelModule.cs
- …
- UIControllers绑定不同panel上要实现的功能
- Localization
- LocalizationManager.cs
- LocalizationText.cs
UI动画 Dotween插件
用字典实现缓存池 TryGetValue函数 减少重复导入