当前位置:   article > 正文

Unity UI架构设计理念_unity 架构设计

unity 架构设计

Unity UI架构设计理念

https://www.jianshu.com/p/e64347dff4fe

Unity UI架构设计理念

1.以ARPG为例,多个场景会反复出现相同的“UI窗体”,造成多个场景中反复加载相同的UI窗体。

解决方案:

                “UI框架” 需要缓存项目(例游戏项目)中常用的“UI窗体"。

 

2.开发商业复杂项目时,各个UI(UI脚本)之间传值,容易出现“紧耦合”(相互交错,你中有我,我中有你)的情况。

解决方案:

                各个UI的生成、销毁、切换,都是通过框架(Manger)实现,各个UI之间不直接联系(传值)。

 

3.卡牌、RPG等游戏类型项目,很多情况下会出现“UI窗体” 叠加现象。开发人员需要“手工”维护窗体中间的层级关系。

解决方案:
                设计UI框架系统,使用“栈”的数据结构,保存与控制当前所有需要显示的“UI窗体”的层级关系。

 

4.商业开发项目中的多个“UI窗体” 之间叠加出现时,必须保持“模态窗口”类型,否则容易出现误操作。

解决方案  

设计的框架本身,需要对当前显示的窗体做“遮挡处理”,即:不允许用户绕过当前

“UI窗体”直接操作底层窗体,或者误操作点击项目中的3D游戏对象等

 

5.从以上问题还可以推导出如下“UI框架”需要注意的设计问题:

        UI框架,需要管理加载“窗体预设”,进行自动加载的管理

        UI框架,需要支持不同的语言环境,即语言的国际化。

        最后设计UI框架一个总的核心原则是:    

        尽量让框架本身完成与具体业务无关的事务性工作,让开发人员只需要专注游戏业务逻辑的开发即可。(这个原则同样适用于其他框架的设计中)

 

 

首先开发最简版本功能设计:

  1:窗体自动加载管理。

  2:缓存UI窗体。

  3:窗体生命周期管理。

UI框架的核心类设计

  1: BaseUIForms 基础UI窗体(父类)

  2: UIManger.cs UI窗体管理器

  3: UIType 窗体类型

  4: SysDefine 系统定义类

在Unity5.5安装目录下,建立脚本模版。

建立必要的目录结构与核心类,导入素材。

 BaseUIForms.cs

 UIManager.cs

 UIType.cs

 SysDefine.cs [Config目录下]

导入UI贴图素材。

导入一些简单的UI素材即可。

 

建立框架中的三个重要枚举类型,定义 UIType 类。

      UIFormsType   UI窗体(位置)类型

      UIFormsShowMode  UI窗体显示类型

      UIFormsLucencyType  窗体透明度类型

 [提示: SysDefine 中定义]

 

定义“基础UI窗体” BaseUIForms

定义 “UI管理器”  UIManager

       1: 定义“窗体路径”与“窗体预设”的集合字段。

       2:定义“窗体预设”与管理脚本加载用的节点对象。

       普通节点、固定节点、弹出节点、管理脚本节点。

       3:Unity编辑器中,定义“Canvas 根窗体”预设。

               1>在测试场景中建立UI Panel 。

               2>共建立3个Panel,与一个挂载脚本的空对象。

               3>建立UI摄像机,设置参数。

               4> Game视图定义800*600 分辨率。

               5>针对Canvas UI对象,设置合理参数

 

定义 “UI管理器”  UIManager (续)

 4:定义“登陆窗体”、“选择角色窗体”、“主窗体”等。

          1>建立各个窗体的Panel (注意:必须在Canvas 内部建立)

          2>给各个窗体添加背景贴图与必要按钮等。

          3>定义的窗体都作为“预设”

定义 “UI管理器”  UIManager (续)

 5:继续开发UIManger 脚本,实现窗体的加载功能,且测试。

          1>主场景中,确保拖拽到层级视图中的Canvas预设正确显示。

          2>编写Awake 事件函数,对于常量都统一定义在SysDefine中。

          3>编写“显示UI窗体”公共方法。

          4>框架外建立测试脚本,测试UI窗体的基本加载功能。

             1]建立框架外启动加载脚本。

             2]针对每个“窗体预设”都需要建立对应的窗体脚本(继承BaseUIForms)

 [备注:如果出现“baseUIForms==null, 请先确认克隆对象上是否加载了BaseUIForms的子类”,说明“窗体预设”上必须添加BaseUIForms 的子类]

}定义 “UI管理器”  UIManager (续)

 5:继续开发UIManger 脚本,实现窗体的加载功能,且测试。(续)

  5>  测试以上所有步骤,成功如下图所属。

窗体层级管理

什么是“栈”数据结构?

  是一种“先进后出”的数据结构,是一种常用算法。

  生活中的“汉诺塔”游戏、“摞烧饼”、“盘子堆”都是一种典型的“栈”结构。

 

C#语言中提供 Stack泛型集合,来直接实现这种结构。

常用属性与方法:

Count 属性 查询栈内元素数量

Push()     压栈

Pop()      出栈

Peek()     查询栈顶元素

nGetEnumerator() 遍历栈中所有元素

  演示:典型Demo示例。

开发“UI管理器”的“栈”数据结构,维护窗体的层级结构。

定义Stack 类型字段。

显示UI窗体 ShowUIForms() 方法中

        1>“反向切换”属性的窗体,定义“压栈”方法

关闭(或返回上一个UI)窗体方法中

        1>“普通”显示属性的窗体,定义关闭方法。

        2>对于“反向切换”属性的窗体,定义返回上一个窗体的方法(即:关闭)。

显示UI窗体 ShowUIForms() 方法中

         1>“反向切换”属性窗体,定义“压栈”方法

         2> “隐藏其他”属性窗体,定义显示业务逻辑方法

关闭(或返回上一个UI)窗体方法中

         1>“普通”显示属性的窗体,定义关闭方法。

         2>对于“反向切换”属性的窗体,定义返回上一个窗体的方法。 (即:关闭)。

        3>“隐藏其他”属性窗体,定义关闭逻辑方法

在多个UI业务窗体中,有时候需要客户端程序主动清空“栈集合”中的当前数据,防止业务逻辑混乱。

 例如: RPG中的“商场系统”、“背包系统”、“任务系统”等。

 

具体代码实现:

  1:在UIType 类中,定义是否需要“清空反向切换”的字段(或者属性)。

 2: 在UI管理器脚本中,关于显示UI窗体的方法中,加入判断清空栈中数据的业务逻辑即可。

定义如下窗体编写代码测试UI框架功能:

Ø登陆窗体:

        注意事项: 所有窗体脚本都要继承BaseUIForms

        定义本窗体的类型(位置、显示、透明度三大属性),不写则采用默认数值。

    `    注册窗体按钮事件。

Ø选择英雄窗体:

Ø主城窗体:

Ø商城窗体:

Ø商品信息窗体:   

Ø程序重构发现,在UI框架内部与客户调用程序中都存在一些反复被使用的技术。

        对于层级视图的节点查找。

         (扩展方法)

        获取子节点(物体)的脚本

        给子节点(物体)添加脚本

        给子节点(物体)添加父对象

 

Ø程序重构发现,在客户程序(UI框架)调用中,会反复出现一些常用的定义方式,例如:

        按钮的事件监听与注册方法    

        打开指定窗体

        关闭指定窗体

        发送消息

        显示语言信息

 

模态窗体管理

UI窗体中,很多弹出窗体要求玩家不能点击“父窗体”,这就是“模态窗体”。

这里我们设计了四种模式类型:

        完全透明、半透明、低透明度、透明且可以穿透。

 

在Canvas根窗体预设中(PopUp节点下)定义“UI遮挡面板”(_UIMaskPanel)窗体。

“UI遮挡面板” 就是一个普通的Panel。

 

平时这个面板是“不可见”状态。

当需要进行“模态”显示的时候,则定义脚本,控制其在PopUp节点下倒数第二的位置,起到遮挡作用。

定义一个专门的控制脚本:“UIMaskMgr.cs”,以及在“窗体基类”(BaseUIForms.cs) 中控制“遮挡面板”的显示与隐藏。

 

框架配置管理

所谓“配置管理”是指一个游戏项目(软件项目),很多需要经常变化的需求或者数据,最好以配置文件的形式存在,从而代替“硬编码”方式。

  例如: 游戏项目语言的国际化、

         日志文件的保存路径等。

 

目前(2017)国际国内普遍采用的配置管理方式主要有两种: XML与Json 方式。

  两者各有优缺点:

           XML:对于数据的精确表示、易读性很高。

           微软很多的项目都内置对XML作为配置文件的支持。

         (例如:网站项目:ASP.Net、 WinForm 等)

           缺点是读写速度慢,这个问题在移动端尤其突出。

  Json: 读写速度快,但是易读性没有XML好,但是可以接受。

           所以本框架项目都采用Json作为配置文件。

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

JSON 语法 (JSON 语法是 JavaScript 对象表示语法的子集)

特点:

 数据在键值对中,数据由逗号分隔。

 花括号保存对象,方括号保存数组。

JSON 数据的书写格式是:名称/值对。 "firstName":"John"

 

开发Json配置管理器

定义通用配置管理器接口

开发实现IConfigManager 接口的通用配置管理器

 

UI管理器中关于“UI窗体预设路径”集合中,把前面“硬编码”改为应用Json 配置管理的方式。

     第1步在Resources 目录下建立关于“UIFormsConfigInfo”的Json 文件。

     第2步对于UIManager.cs 中的“UI窗体预设路径”集合做配置管理。

 

日志调试

日志调试在游戏的开发全过程中占有非常重要的作用。

自定义“日志调试”脚本插件的开发思路与具体实现。

  现在为了更好的适用于PC与移动端调试的目的,进行再次重构。

  第1:对于读写文件内部方法做重构完善,使得日志文件实现自动侦测与创建写入操作等。

  第2: 改以前的针对XML的配置文件的读取方式为Json 文件的读取。

  目的一:提高读取速度。

         二: 更好的应用在移动端的部署

消息传递中心

基于Unity技术的游戏与项目研发,目前提供的消息传递方式种类少,且耦合性很高。

 1:脚本组件公共方法、字段的相互调用。

        例如: GetComponnet().TestMethod();

 2:SendMesage 技术。

 3:单例模式数据传递。

开发一种低耦合,无需考虑被传递对象(脚本名称、组件名称)的技术非常有价值。

“消息传递中心”:

  基于观察者模式,利用委托与事件的基本机制原理,进一步封装重构的技术实现。

定义MessageCenter

 基本原理:

 

 

窗体基类(BaseUIForms) 中对于“消息传递中心”类常用方法的封装。

     发送消息 SendMessage()

     接收消息 ReceiveMessage()

客户程序消息传递多组数据的演示。

客户程序建立“系统常量”类,方便程序复用与集中化管理

 

资源国际化

“资源国际化”对于游戏项目开发是指:语言、语音、贴图、模型等国际化问题。

对于游戏项目,最常见的是针对不同国家的多语言版本的开发,也就是“语言的国际化”。  

多语言版本的实现,最基本的原理就是根据ID去读取语言配置表,不同的语言新建一个语言配置表。

 

定义“语言管理器”(LanguageMgr)

基本原理:

      1: 使用配置管理器脚本(继承 IConfigManager接口),读取不同语言的Json配置文件。

      2: 使用 Dictionary 集合缓存“语言键值对”。

      3:定义显示方法,根据ID查询出对应的语言信息

 

UI窗体基类(BaseUIForms) 对显示语言的重构。



作者:Magic_Dong
链接:https://www.jianshu.com/p/e64347dff4fe
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号