《Unity3D高级编程之进阶主程》第二章,架构(三) - 架构的误区,如何做前端架构,以及如何架构Unity3D项目

前文回顾 架构(一)

    对软件系统架构进行一个彻头彻尾的解释。什么是软件系统架构,为什么需要软件系统架构,以及什么样的软件系统架构才是好的。还包括介绍了,抽象构建架构的思维方式。

前文回顾 架构(二)

    对软件系统架构抽象的思维方式进行了一番详细介绍,包括了分层,分治,演化。

这篇我们将来具体介绍下,架构的误区,如何做前端架构,以及如何架构Unity3D项目。

===

前端架构与后端一样有难度

后端架构的目标是,高性能、高可用、可扩展、安全。那么前端呢?目前是高性能、高可用、可扩展、安全?对前端来说数据库不用选,语言不用选,框架三选一,架构就简单了?我认为这是对前端的关注点理解不到位的体现。

作为前端工程师,关注点是什么呢?首先就是用户体验。用户进入游戏快不快,用起来爽不爽,会不会觉得卡,会不会觉得Low。这才是前端最该关注的东西。

所以前端架构跟后端比起来,看起来又点不太高大上,因为很多都是细节问题。如何让游戏加载更快,如何把不必要的代码干掉,如何让用户加载最少的内容,如果让用户最快看到效果,同步还是异步加载。

有人说前端技术架构师,还不如说是用户体验师,或者前端优化师。跟后端不是同一个世界的。

如果单单是说前端用户体验师,前端优化师,那么谁来做,那些游戏底层的代码的框架呢?前端的架构中有很多需要我们搭建的框架,包括网络框架,UI框架,数据框架,编辑器,模型动作框架,AI框架等。

所以前端架构一点都不比后端容易,甚至更加费力。因为我们需要关注的细节更多,包括多种平台的编码,以及多种语言的相互调用等。

培养架构设计思维

良好的架构设计思维的培养,离不开工作中大量高质量项目的实战锻炼,然后是平时的学习、思考和提炼总结。

基本的架构设计思维,其实在我们大学计算机课程(比如数据结构和算法)中可以找到影子,只不过当时以学习为主,问题域比较小和理想化。所以大学教育其实非常重要,基本的架构设计思维在那个时候就已经埋下种子,后面工程实践中进一步消化和应用,随着经验的积累,我们能够解决的问题域复杂性和规模逐渐变大,但基本的武器还是抽象、分层和分治等思维。

架构设计不是静态的,而是动态演化的。只有能够不断应对环境变化的系统,才是有生命力的系统。所以即使你掌握了抽象、分层和分治这三种基本思维,仍然需要演化式思维,在设计的同时,借助反馈和进化的力量推动架构的持续演进。

架构师在关注技术,开发应用的同时,需要定期梳理自己的架构设计思维,积累时间长了,你看待世界事物的方式会发生根本性变化,你会发现我们生活其中的世界,其实也是在抽象、分层、分治和演化的基础上构建起来的。架构设计思维的形成,会对你的系统架构设计能力产生重大影响。可以说对抽象、分层、分治和演化掌握的深度和灵活应用的水平,直接决定架构师所能解决问题域的复杂性和规模大小,是区分普通应用型架构师和平台型/系统型架构师的一个分水岭。

如何架构Unity3D项目

我们用分层的思维方式,先确定架构的层级,如下图。

Unity3D架构1

把整个项目分成五大层级,网络,数据管理,资源管理,主要逻辑框架,UI框架。

这样一分清晰的知道了我们需要做哪几块大类的东西。但是发现这样拆分,太笼统,特别是主要逻辑框架这块,完全是概括性的层级,无法表达具体的系统。所以我们再拆分层级。把太过于笼统的层级进行再分层。如下图:

Unity3D架构2

经过我们的再分层后,把主要逻辑框架分成了,编辑器,角色行为框架,AI框架,地图场景与寻路框架,Shader与特效,设备平台,这些子层都是在主要逻辑层中的。他们有自己的框架,也可以互相调用,构成了主要逻辑部分,也就是核心玩法或者说核心战斗的主要部分。

我们也将资源管理层和数据管理层进行了拆分,分成了Assetbundle资源管理和Prefab资源管理,以及内存数据管理和外部数据管理,这样更清晰的分工了各层的职能。

其实还有很多其他的层级我们这里没有提到的,包括常用库,工具库,动画控制等。

在游戏项目中最常用的是,数据表,网络层,UI层,常用库,这几个了。我们可以用这个层级的方式来试着搭建一个完整的项目,只是做抽象上的编写,就可以清晰的知道,这个项目需要哪些模块和层级了。

比如做一个单机的策略类游戏,可能就没有很多角色上的东西,而多了很多2D动画行为控制上的需求。这时我们就可以把层级划分下,把注意力重点放在,2D动画行为控制,UI框架,数据管理,资源管理,以及AI上。

比如做一个3D人物角色为主的网络游戏,就有地形地图,角色行为控制,甚至需要一套角色技能特效动画编辑器。这时我们就需要把网络层这块好好决策下该用哪种框架,TCP-Socket?UDP?还是web形式的HTTP?!3DMMRPG主要难度集中在了,角色行为控制和AI,以及地图与寻路上。我们可以重点划分出来,找人专门做这块,把最难把控的放在最优先的位置去做。

而后再对这些层级进行细致化的构建。这时我们可以用分治法,因为具体某个要解决的内容已经确定了,而这个内容或者问题还太大,无法进行直接的下手,我们需要对分治,把一个问题分成几个小问题来做,以最终完成这个内容。

拿网络层来说,我们进行分而治之,如下图:

Unity3D架构3

图中把网络层先拆分成http,tcp-socket,udp这三种形式,再对具体的接口进行了拆分,对于拆分出来的每个接口,如果还不能直接使用再进行细致的拆分,直到拆分到可以具体实施了为止。图中先将接口拆分成,连接,断开连接,发送数据,接受数据,以及网络事件,再对每个接口进行拆分,把接口需要做的事拆分出来各个击破。

其他层级部分的框架也是同样的方式进行分解,用分而治之的方法逐个攻破。这里简单描述下各个模块的拆分。

数据表--从XLS导为2进制文件还是CSV或其他格式。

UI层--使用NGUI还是UGUI,界面基类怎么定义,界面管理如何做,输入事件如何管理。

外部资源管理—是否使用AssetBundle,AB如何分类打包,有没有共享AB,什么时候该释放AB资源。

AI层—使用状态机还是行为树或者其他,状态机如何实现,行为树工具要怎么做。

地形地图—地图是2D还是3D,是使用自带地形还是自己做网格地形,是否需要Mesh合并,地形上小东西怎么处理,如果地形过大,在游戏里该怎么逐步显示。

寻路与网格—使用A星算法还是其他,自己写寻路还是借助插件,网格怎么生成,方格还是三角形,地图过大时A星寻路会超时,如何处理。

常用库—时间转换,数学函数,数字变量加密封装类,坐标转换函数,Debug信息开关等等

角色行为控制—前进,后退,左右移动,跳跃怎么处理,技能中特效怎么跟人物挂钩,技能移动怎么修改和编辑,是否需要技能特效编辑器,换装编辑器。

2D动画控制—帧动画需要封装吗,2D骨骼动画需要封装吗,2D人物动画行为如何控制,技能制作是否需要写编辑器,2D动画特效是否有制作流程。

对层级和模块逐个攻破的同时,也进入架构演化模式。一开始的做的架构中某个部位的不适合,或需要改善,从而进入了完善修复的演化模式。

本来抽象简单的架构,开始复杂化。每个模块都在有条不紊的开发中,不断会冒出各种各样不适应或者不符合实际需求的问题出现,我们需要及时跟进演化内容。去除重构,或者修复,前面由于各种原因而导致的错误架构或者错误理解。

关于架构心得

好的架构控制,是简单而无障碍,所以说架构设计更多从“情理”而不是“当前事实”来看的,架构以简单为美,但这种简单的是以对未来的复杂度的良好容忍为前提的。身边看到的不少糟糕的架构设计,主要问题就是要解决的所有问题域,都在同一个,或者同一层名称空间内。比如实现一个系统库,用户用不用线程都不知道呢,就开始在数据架构上下加锁,美其名曰“线程安全”,这就是典型的把两个互相独立的逻辑空间混合了,以后增加功能的时候,一脚踩进去,会踩死多少个功能都完全无法预期了。

所以,架构设计的代码或者文档,都是以有述无,写的是你看得见的代码,心思都在没有写的代码身上。如果你把心思都放在写的那些代码上,那架构设计就变成详细设计了。架构设计无法学样子,问题就在这个地方。

感谢您的耐心阅读

Thanks for your reading

  • 版权申明

    本文为博主原创文章,未经允许不得转载:

    《Unity3D高级编程之进阶主程》第二章,架构(三) - 架构的误区,如何做前端架构,以及如何架构Unity3D项目

    Copyright attention

    Please don't reprint without authorize.

  • 微信公众号