首页 > 学院 > 开发设计 > 正文

UI框架的思考

2019-11-09 17:36:57
字体:
来源:转载
供稿:网友

以下列举UI系统中的要点,脱离出引擎,保留设计思想。

结构

UISystem 负责管理UIWndUIWnd是所有UI的基类拓展UI公用组件,模块间公用,例如公共弹窗,UIIcon等

接口设计

我觉得接口非常重要,即使不同项目之间,重用率也非常的高。public interface IBaseWindow{public void Show();public void Hide();public void Destroy();public void BringTop();public void SetDepth(int value);public System.Action OnClose;public System.Action OnFinshShow;}interface IWindowAnimation{void EnterAnimation(EventDelegate.Callback onComplete);void LeaveAnimation(EventDelegate.Callback onComplete);void ResetAnimation();}public interface IStack{public void Clear();public void Push(UIWnd wnd);public void Pop();}

UI层级管理

解决不同ENUM_LAYER_TYPE的层级问题

enum ENUM_LAYER_TYPE{NONE,DEFAULT, //深度0TOP, //深度1000POPUP, //深度2000GUIDE, //深度3000LOADING, //深度4000COUNT}假如:A是TOP类型(预设深度200),B是POPUP类型(预设深度200)A的实际深度为1200,1000<A(1000+200)<2000B的实际深度为2200,2000<B(2000+200)<3000

解决相同ENUM_LAYER_TYPE的层级问题

例如:同样是DEFAULT的A、B、C首先创建A,自动分配深度为0再创建B,自动分配深度为A的深度+1,B的深度为1在创建C,自动分配深度为B的深度+1,C的深度为2

如果我希望A在最上层,因为他们被存入保存在同为DEFAULT的字典中,找出除了A以外最大深度N,把A的深度设为N+1.public class UISystem : MonoBehaviour{Dictionary m_wndDic = new Dictionary();public void BringTop(string value){//找到m_wndDic 中除了A以外最大深度N,把A的深度设为N+1.}}public class UIWnd : MonoBehaviour{enum ENUM_LAYER_TYPE LayerType = ENUM_LAYER_TYPE.NONE;int Depth =0;public void BringTop(){UISystem.Instance.BringTop(gameObject.name);}}

UI导航

例如:ABCDA顺序打开界面,然后一路返回,要求能回到A.可以考虑用栈来管理,把UI分为2类:入栈型:普通非入栈型:常驻内存,例如UITop不会入栈

防错机制:对栈UI数量进行评估,超过N个,如何处理?例如只保留最上层,清除所有下层UI

分两种情况:

常规出入栈

清空栈,再入栈

Stack m_uiStack = new Stack();void Push(UIWnd wnd){//在UI创建时会把非常驻型UI添加到这个栈中,不能重复添加同样的}public void Pop(){//当返回时会从栈中取对象并刷新UI}

UI间的通讯

这两个使用起来比较顺手,另外可借用更多设计模式来解耦,例如外观模式。

消息分发,调用EventDispatch

各模块自己去监听消息

P2P,UISystem.FindWindow()直接调用

从UISystem中查找目标UI,注意空引用

UI动画

主要指入场/出场动画,一般是根据UI的类型来确定动画效果,各模块不用自己去写。我喜欢玩王者荣耀,它的UI动态效果让人感觉有活力、很舒服。像PVE界面还特意加强了动态UI。enum ENUM_WND_TYPE{NONE,POPUP, //弹出窗口RETURN_FULL_SCREEN, //全屏有返回窗口DONOT_RETURN_FULL_SCREEN, //全屏无返回窗口GLOBAL, //全局窗口COUNT}public class UIWnd : MonoBehaviour{void onShow(ENUM_WND_TYPE type){switch(type){//具体的动画//动画后的回调}}void onDestroy(ENUM_WND_TYPE type){switch(type){//具体的动画//动画后的回调}}}

本地化方案

不考虑这些,等做海外版的时候就蛋碎了涉及到图片、字符串、音频,必须考虑如何便捷的切换

字符串

所有用于UI显示的字符串不允许直接写在脚本里,也不要写在预设中,而是从xml或者Excel通过id读取//例如我需要字符串"系统错误"string str= TextSystem.Instance.GetText(101);//TextSystem负责根据语言类型从xml中读取

如果大量信息并且使用频率不高,可以考虑用html5的展示,给个外部链接。参考王者荣耀的英雄攻略界面。

IMG_4588.PNG图片和音频直接替换尽量少用图片字体

特效

例如黑屏、高斯模糊、边缘模糊,一般非全屏窗口会带一个这样的底图效果特效和UI系统结合时,会有一些裁剪、深度、缩放等问题,需要来解决还需要测试特效对性能的影响,可以进行性能分档,低端机降低或屏蔽特效

搜集玩家操作信息

UI框架最好能集成常规数据结构搜集的接口,这对运营非常的必要,例如大量玩家在XXX页面做了XXX操作后就流失了,而不是程序异常导致,基于这个行为来分析流失原因。

常规统计:进入页面、退出页面、与服务器通讯操作、模块停留时长、切到后台和恢复的时间,以及角色数据相关的

我们经常谈DAU、MAU,却无法分析玩家流失原因、回归原因,基于这些数据来分析更靠谱一些。

总结

基于插件和需求去定制自己的UI框架,例如Unity的NGUI,itween,poolManager等集成公用UI组件,提高开发效率对性能的评估、资源的管理都需要提前文档规划和测试,对产品有整体把控UI热更新,需要提前定制自己的热更方案来应对版本迭代,产品运营期间非常重要可视化编程,Unity编辑器扩展做到这点,对Debug和提高开发效率很有帮助,可看看UFrame设计模式,例如常见的MVC、StrangeIoC、MVVM等,选定适合的提前做好UI开发模板,不然很难推广收集玩家操作信息,分析玩家心理
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表