基于NGUI的unity界面管理的讨论

写在前面

刚刚做的项目,由于界面管理做的不太好,所以在开发的过程中出现了很多奇怪或难缠的bug,搞得我们几个写UI逻辑的越写越觉得没意思,想方设法的到处打补丁,后来也就是在这样的情况下,一直在总结开发中关于界面上遇到的坑,写了一年多的UI逻辑,针对那些由于界面架构上导致的问题,自己琢磨了一个简易的UI框架,只是简单的跑了一下没什么问题。

好了正式开始吧。

关于界面的问题(我开发时遇到的)

这个可是太多,总结了几个重要的点
1. 界面的管理
2. 界面生命周期
3. 界面的显示和隐藏
4. 界面逻辑的管理
5. 逻辑代码和view分离
6. 界面之间传值问题
7. 界面穿插和界面层级管理
8. 引用关系
9. 脚本该不该挂在gameobject上

那么下面我就围绕以上几点写了。

界面管理

界面的资源全部都是打在AssetBundle中,然后通过底层函数把prefab load起来,给它挂上一个脚本,这个脚本就包含着该界面的逻辑,有一个WindowManager来管理这些window,每个window之间有父子引用关系,在WindowManager中还维护了一个栈来管理,每次界面打开或关闭都与该界面的父或子有关系。

例如,当打开一个新界面时,会把父界面的gameobject传进去,把界面显示出来,把父界面隐藏,关闭界面的时候,把当前界面隐藏,父界面显示,这样会出现一个问题,当两个界面同时在最上面时,当它们无论关闭时都会下面的界面显示出来,有时候就会出现穿插。

正常情况下,在同一时刻应该只允许一个界面是可操作的。

又是维持父子关系,一方面又用栈来保存,这样让我真的不知道应该怎么获取父界面,因为有可能在界面中父的引用不是栈里面的“父”。

界面生命周期

界面的生命周期可说是个比较重要的问题,提醒一下!!!千万不要把两个不同的生命周期顺序写在一起,如果真要写一起,请一定一定注意它们之间的顺序。

自己的界面生命周期函数的调用时机一定要很清楚。

说说我们项目,挂在界面上的那个脚本里面就存在两套生命周期函数,一个是Mono的那一套,另一个是底层框架维护的一套。这东西当开始的时候没什么问题,越往后写越改就发现很多时候的bug,都是由于生命周期顺序造成的。例如:NGUI里面很多东西都是在Start做的,所以只要用NGUI,所有设置界面显示都最好是在Start之后去调用,不然可能会出现ScrollView的Item错位的情况。

我们界面几个状态,可见、可操作、不可见。转圈的进度条也被用界面来管理了,所以当时每次转圈完了之后,就会调用一次“可操作”的周期函数,有时候遇到断线重连,就会不停的转圈,当然也会不停的调用函数。

界面的显示和隐藏

有很多种方法
1. gameObject.SetActive(true or false)
2. 把界面移到UI摄像机外面
3. 改变界面的Layer到UI相机不照的层
4. 设置为透明
5. 用不透明的背景遮挡
6. 每个界面都放在不同位置上,这样移动UI相机到相应界面也实现显示隐藏了。
7. 也可采用多相机的方式

其中1、4两种方法对于NGUI并不好,因为那样操作会导致panel的所有“顶点重建”,重新生成drawcall。这也是NGUI消耗性能的地方,过段时间我会整理一下对NGUI的分析。
其中5,要看具体需求(自己脑补)
其中2、3、6、7都是可取的,但具体细节还得认真考虑,我用了改变Layer的方式。

界面逻辑的管理

我们直接在上挂了一个脚本,刚开始做unity的时候,把界面的逻辑全部写在这个脚本里面。一般简单界面还好,但遇到复杂界面就完蛋了,有时候这一个脚本就得上千行,可读写性很差,过一段时间修改原代码很费劲,而且很多逻辑状态放在一起非常容易出现bug,有一段时间bug特别多。

遇到了一个状态非常多的界面,脚本里面放了很多状态变量,有些变量是互斥的,有些可以共存的,然后就这样没有规划的写了,结果这个界面很乱,都不敢做太大改动,出了bug改好了又引发其他的bug。所以后来就用有限状态机来管理这些,把每个状态和状态对应的逻辑拆分,这样每个脚本行数变少了,逻辑得到很大的改善,后来改bug都不费脑子了,呵呵。(后来在知乎上看到一个人说用行为树。。。后面再尝试吧)

逻辑代码和view分离

为什么?

  1. 当业务代码越复杂时,修改代码就成了费脑的事情。
  2. 当时间越来越久,理解代码就非常困难。
  3. 同一个逻辑不能复用,在很多地方复制粘贴,如果出现错误就会修改很多地方。
  4. 测试变得非常麻烦,没都要整体测一次才能确保一切完好。

怎么做?

使用MVC或MVP等架构模式,使代码达到低耦合、高复用、易测试、好维护、易扩展。

记得刚刚学习网站开发的时候,MVC是首先接触到的设计思想,应该滚瓜烂熟的东西。有一段时间我研究了一下MVC,发现和之前的认识不一样,比如View需要观察Model,MVC实际是UI框架的一种模式,可并不是整个系统。下面就看看那些模式:

  1. MVC
    是一种使用Model View Controller设计创建web应用程序的程序。它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。最典型的MVC就是jsp + servlet + javabean的模式。

    Model - 表示应用的程序的核心,提供数据和数据相关的逻辑,通知View数据变化
    View - 显示数据,观察Model变化,可以从Model取得数据进行显示
    Controller - 处理输入,调用model处理业务逻辑,逻辑处理完之后,修改Model,并选择View显示结果
    注意:这里所说的是经典MVC模式,后来发展了很多版本,它们之间无非就是这三者关系的变化,具体可以看看相关的文章和论文。

    这里写图片描述

  2. MVP
    它是从MVC演变而来,其中Presenter处理业务逻辑,Model提供数据和数据的逻辑,View负责显示。
    作为一种新模式,和MVC的重大区别就是在MVP中View不直接使用Model,它们之间通过Presenter来进行的,所有交互发生在Presenter内部,Presenter代替了Controller的角色,在处理业务逻辑的基础上还要负责帮View从Model中取数据。而在MVC中,View会直接从Model中读取数据。

    这里写图片描述

  3. MVVM
    对MVVM不了解,也没有使用过,看了一些网上的文章,最重要的概念应该就是:数据绑定。把Presenter换成了ViewModel,换汤不换药,最终发生改变就是三者之间的关系和三者所负责的事情。了解更多就去网上搜一搜。

以上对一些模式的简介,总结起来,虽然有这些模式的存在,但需求是万变的,没有哪个模式能适用于一切情况,所以一切都要以实际项目、实际需求为主,吸收那些模式的

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值