前言
今天的主题是《大型实时竞技网游开发之:深入架构与优化》
为什么会有这个主题呢?因为很多同学在学习游戏开发的课程时或者碰到大型网络游戏项目时,就会有这么几个问题:
不知道如何制作一个大型的游戏项目
实时竞技游戏的实时性如何表现
回合制或慢节奏的游戏里碰不到的问题会显现出来
所以今天的课程就是帮助大家解决这些问题,会讲解在开发大型实时竞技网游时该如何做,如何优化,这就是今天课程目标!
版权声明
本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源
机构介绍
![]()
优梦创客:我们的目标是帮助各位同学创作一款大家爱玩的游戏
我是今天课程的主讲老师雷蒙德,在行业内有14年的从业经验,做过程序员、技术经理、教学经理,目前的是我们优梦创客的创始人
下面是我曾经参与制作过的一些成功的项目作品,包括有:《传奇世界》,《神迹I/II》,《疯狂赛车》,《Infinity3D引擎》,《剑网三》等
主题
![]()
今天的课程主题:
游戏开发可以分成几个阶段?
在什么阶段做游戏的架构,在什么阶段要针对游戏做优化
帧同步游戏的架构有哪些地方需要优化?
代码热更新的优化要点
资源热更新的优化要点
游戏开发的阶段
![]()
游戏开发可以分成五个阶段
第一阶段:此阶段需要确定需求(开发什么样的游戏),进行预研(确定项目能不能做),然后立项(筹备资金与人才)
第二阶段:此阶段需要开发底层库和高层架构
第三阶段:开发业务逻辑
第四阶段:进行游戏测试
第五阶段:里程碑达成(阶段性目标达成,进入下一轮迭代)
注意点
没有人能预见到所有的事情
在软件开发里,唯一不变的是变换的需求
架构不是空谈
不管是在学习中还是在开发项目的过程中,都需要遵循商业项目的规律来做
《皇室战争》商业帧同步项目的开发过程
![]()
S1:项目原型开发
核心游戏系统
从零开始一步一步的实现游戏项目的核心系统,比如《皇室战争》是卡牌实时竞技游戏,那么它的特点就是:
1,离不开卡牌:需要开发卡牌系统
2,离不开卡牌的实时竞技:需要有战斗系统
基础架构支持:
一个商业项目需要有消息系统、UI框架、Shader效果、资源管理、代码热更新等架构支持
大型分布式服务器开发基础
S1里开发的主要是游戏客户端部分,但现在不是网络游戏的手机游戏可能很少了,而且单机游戏很难获得良好的收益,所以要学习开发大型分布式服务器
有同学可能会问:“我在最早开发游戏时可能没有考虑到网络问题,那么我的项目架构该怎样支持网络游戏开发呢?
在商业项目开发中,即使有一个功能现在暂时没有做,也要把它的接口留好,该留哪些接口是由自己的开发经验所决定的
在大型分布式服务器开发阶段里能学到:
分布式服务器
客户端跟服务器的通信流程
怎么样保证服务器的高性能
而且我们的服务器冗余非常小,当你把服务器的协议定义好以后,架构会直接帮你把服务器的数据库、服务器跟客户端通讯的协议生成好
S2:帧同步的客户端和服务器架构
什么叫帧同步呢?
传统的网络游戏,就是玩家发出一个操作到服务器,服务器接受到后会计算,然后传递给客户端,比如把攻击防御的结果返回给客户端,如果是移动操作,就会发送移动后的角色坐标给用户的客户端
但传统方式在游戏过程中要传输的数据量是很大的,因为服务器向玩家客户端传递的数据量就已经很大了,还要把这些数据同步给其他客户端
那该怎么办呢?
可以采用帧同步,帧同步就是当玩家执行某一个操作后发给服务器时,服务器不会做运算,会直接把这个消息广播给所有客户端
比如移动命令,玩家操作传到服务器,服务器不会做运算,而是直接把消息广播给别的客户端,它的通讯量只是你按了几个键、按了什么键而已
《王者荣耀》就是采用帧同步来实现战斗的,所以《王者荣耀》的实时性和打击感做得很好。这是什么原理呢?
因为它把所有的运算都放在游戏客户端,这时服务器的性能瓶颈就只有它的数据传输能力和转发能力
这是帧同步架构服务器的能力要求,我们的项目需要能够适应这样的服务器架构
做完服务器架构设计和功能实现以后,还需要机器人压力测试,我们的服务器是能够明确支持万人同服的,这不是玩具代码所能够实现的功能,而是一个真正的商业项目架构
一个玩具项目就是写完数据库的协议、还要写网络协议、序列化协议、没有数据缓存,也没有实时竞技的元素,那么这个项目的难度、对学习能力的锻炼、通过实战项目锻炼的价值就没有那么高
帧同步的难点在哪里呢?为什么说帧同步游戏是一个实时竞技游戏呢?
我用《皇室战争》项目举个例子:
我出了一张卡牌,在这张卡牌变成游戏单位行动时,它是由你来控制的吗?不,它是由游戏的AI来控制技能释放、进行战斗的
所以它的游戏AI系统会非常复杂,而且由于所有的运算都是每一帧实时运算的,你在开发那些慢节奏游戏时碰不到的问题都会在实时竞技游戏里暴露出来,你在实时竞技游戏中所得到的锻炼跟传统的回合制游戏也是不一样的
而且帧同步有很多开发要点,客户端有很多坑点和可以对你形成经验的点,一些同学只是学习了S1加S2包括前面后面的一些基础知识和后面的面试准备,就能使面试官对他刮目相看
S3:双端热更新
前面的S1课程已经实现了代码热更新,但S1中的代码热更只是在客户端中进行热更,在S3里会再次深入代码热更新,学习客户端热更和服务器热更
有同学可能会说:服务器要热更新干什么?
如果你有一个大型的游戏项目,而这个项目经常需要停服热更的话,那这对游戏公司的运营损失是很大的
而且当出现一些小bug或者一些比较严重的bug时,当前又暂时不能停服时,就可以实现服务器的实时热更新来解决这个问题
当然了,实时热更新不是直接在生产服务器上更新,而是会先在开发服务器上测试,测试通过以后才会把它更新到支持热更新的服务器上
客户端热更部分
ILRunTime能够很好的支持客户端的热更新,并且不需要学另外一门编程语言
传统热更新是用Lua来做的,我们之前的课程也是用Lua来做热更新,另外我们的Lua课程讲的也是非常不错的,我们从基本的使用到Lua在ToLua、XLua中使用、它的底层原理、性能瓶颈点、源码实现、Lua跟C#的脚本绑定、GC的开销、方方面面都对它做了系统的分析
不管是用ToLua、XLua、还是用ILRunTime,都需要对底层原理进行学习,如果不学习底层原理,那要怎样理解它的优化方式呢?怎样把这个东西用好呢?
所以S3阶段不是针对某一项技术,而是要学习方法,理解它们的原理
S4:发现问题,解决问题,项目迭代
将学完S1课程后就能够面试客户端开发;S1、S2学完能够高薪入行;如果你是有经验的开发者,想要进一步提升,那么建议将学完S2加S3,并且要对S2和S3的内容有充分的理解
老师也会在笔试、面试模拟环节帮助大家进一步巩固知识,提升对知识的理解,当然还有其他方式也能帮助大家理解知识,比如一对一指导和每周直播
S1到S3实际上就是从原型开发到项目架构到具体功能实现的过程(也包括了项目的迭代),到S4以后就相当于商业项目进入了后期
在这个过程中可能会发现有各种各样的问题,如果你平时只是做UI、做逻辑、接SDK,你可能发现不了这些问题,因为这些问题都是我们从规模、架构、底层实现的角度提炼出的,我们也会教大家如何解决这些问题
大家如果想知道我们在S4课程里是如何发现问题、解决问题、做项目迭代的话,可以在文末加一下爱丽丝老师来了解课程详情
架构优化
![]()
1,退出战斗或游戏时报错
这是很多同学在开发小型游戏时,想要退出战斗或退出整个游戏项目时会出现的问题
如果你开发的是小游戏,那这个问题不会太明显,因为游戏对象比较少,要处理的数据量也少
但如果你的对象多一点,问题就会很明显,这个问题是怎么造成的呢?
举个例子:有A、B、C、3个GameObject,每个GameObject上都挂了相同类型的组件,每个组件上都有一个Start方法
那么你能告诉我这3个对象是哪个先Start,哪个后Start吗?它可能第一次执行时是A的Start,然后是B,最后是C;第二次启动时可能是B先执行,第三次可能是C先执行
所以它们的顺序是不确定的,那么再假设这三个对象之间有一些依赖关系,比如B中有一个X字段,A初始化的Start方法里有一个Y字段,它是X的平方
那如果现在程序的启动顺序是B先启动,然后A再启动,那么这没有什么问题,但是如果反过来呢?是A先启动,然后B再启动,这样Y就获取不到有效X的值,程序就会报错了
这是程序启动时会碰到的问题,那么在退出时是不是也会遇到一样的问题呢?答案是当然的,想要解决这个问题就需要自己管理程序的生命周期
2,如何管理多次出现或数量较多的对象
举个例子:
有一个角色实体,角色头顶上有一个血条实体,角色身上还有一个挂件实体,血条有自己的属性数值,挂件也有自己的属性数值,那要怎样管理角色实体,以及角色实体身上的血条和挂件呢?
从位置关系上来看这个实体:
血条要跟着实体走,所以它们是父子关系
从数据管理的角度上来看:
血条和挂件是角色实体的一部分
具体要怎么管理,大家可以自己想一想,把你们认为对的答案发在评论区
3,异步性能太低,协程太分散,该如何管理
有些同学会在程序里大量使用协程或者异步,但不管是协程还是异步,都是由CLR框架管理的,并且不管是Lua,还是ILRunTime,它都是一种程序脚本
既然是脚本,那就是有脚本层调用开销的,这就存在性能问题,那么这个性能问题该怎么解决呢?
很多时候我们使用异步主要就是两个目的
1,延时
2,资源的异步加载
如果能解决这两种异步产生的问题就可以取得更好的性能效果
另外还有一个问题就是:如果使用协程呢?
因为异步底层也是CLR通过协程来实现的,如果程序里过多的使用了异步或者协程,那么对CLR的管理开销是比较大的
这就好比在程序中创建了很多的线程,线程的好处是可以一起干活,而多线程的坏处也正是它的好处带来的,因为线程本身带来的开销就是很大的,线程调度带来的开销也是很大的
这就是架构要优化的点,它会出现难以管理的问题,而我们的项目已经把这些问题都解决掉了,所以它跟你自己做着玩的项目是不一样的
4,异步的流程管理
使用异步就会存在一个问题:异步程序会产生很多不能确定在什么时机执行的程序流程
因为异步程序不是在这一帧就启动的,它是在另外一帧或者另外很多帧以后才去执行,而且是定时执行的,不像同步程序,执行顺序很明确
所以异步不便于管理,但有时又不得不使用异步,这就存在一个问题:能不能在不需要用异步时把它同步化
这是要从程序的结构上来做的优化点,如果能实现会带来很多好处
1,可以提高程序性能
2,可以让程序更加稳定
但有时可能不得不用到异步,这其实也是可以优化的,比如下面的问题
5,卡牌”变兵“时的卡顿
这是我们在开发《皇室战争》时碰到的问题:
战斗时的每个兵种、每种卡牌,在第一次放到场景中变成游戏单位时都会稍微卡一下
如果你是一个有经验的开发者,那你一定会碰到测试跟你说这样的问题,而且这是一个非常高频的面试考点,该怎么解决呢?
就是使用对象池,但因为对象池本身也是有使用开销的,使用不当就会在战斗过程中造成更大的卡顿,因为对象池的原理是:
当对象不够时就会创建新对象
所以在战斗时创建对象就会造成卡顿,这在我们的项目中有相应的解决方案
6,对象池中的对象随着战斗单位的增多而膨胀
比如对象池里原本有五个对象,那当这五个对象不够用时有什么处理方法呢?
直接实例化一个新的对象,但它可能会卡顿,特别是战斗的时候
那么应该怎样避免在战斗时实例化造成卡顿呢?而且不停的实例化对象也会造成对象池的膨胀
比如一局战斗中用到了50个对象,这些对象都是从对象池里取出来的,所以对象池里就必须要保证要有50个对象,也就是要实例化50个对象,那么在这局游戏进行的过程中要增加对象或者这局游戏结束了,对象池里的对象不用了,该怎么办呢?
这牵涉到了Mono的内存管理问题,会在我们的课程里教给大家
7,对象池扩容卡顿
8,UI模块逻辑多了难以维护
如果你的UI很简单,只有10行20行代码,或者100行代码,那就不用担心这个问题
但如果有200或者300行代码,甚至是四五百行代码,那你就要注意怎样解耦了
AA的优化
![]()
如何最大化利用AA资源管理的优势
Addressable也是可以优化的,先给大家介绍一下AA的能力:
使用AA可以在一小时以内做完资源热更新功能,传统的AssetBundle方式是不可能达到这种效率的
因为仅仅只是AssetBundle的打包策略选择、打包功能定制、打包工具编写就得花一两天,对于新手可能要一个礼拜,而且资源的释放问题也需要自己处理
但AA只需要遵守AA的编程规范就不会犯错,所以AA很简单,但要把AA用好还需要对AA有更深入的理解,需要掌握AA的底层机制,包括面板上每一个选项的含义
AA能实现自动打包吗?
可以
AA能定制打包规则吗?
要针对AA来实现打包规则定制需要对AA非常熟悉
AA资源冗余能否优化
AA本身比AB(AssetBundle)好的地方就是它的功能拓展,可以通过功能扩展来实现资源冗余的优化
我们的框架对AA本身提出的资源冗余检测和优化方案做了进一步的升级,成为了第二代的资源优化方案
关于什么是资源冗余优化,可以看我之前的关于资源热更新的公开课
AA怎样做到下载时全部更新完毕再进游戏?如何显示下载进度?
AA默认的方式就是资源随用随更新,比如角色模型发生了变化,那么当游戏加载时,AA就会下载这个资源
但这种方式有个缺点:如果在战斗时加载这个模型就会造成程序的卡顿
怎样能做到下载时全部更新完再进游戏呢?
这需要对Addressable的底层的API机制非常熟悉,并且要实现一套完整无错的解决方案
这样就可以下载全部资源再进游戏,并且能显示下载进度
AA远程下载的缓存机制是是什么样的
什么叫缓存机制?
当远程下载的资源过多,不能一次下载完时,就要考虑到:如果资源在下载的过程中断网、或者因为信号不好而下载中断了,那么是要重新把资源下载一次吗?AA会重新下载资源吗?如果要重新下载资源,那怎样最小化资源的下载量呢?这都是商业游戏项目需要考虑的
如何打包才能达到资源更新的最小开销,并且能够合理的验证资源的版本是否更新?
需要理解一些AA的打包优化策略
ILRunTime优化
![]()
游戏战斗过程中,游戏单位增多时GC开销比较大,CPU运行卡顿
这个问题无关使用ILRunTime还是用ToLua,它们都会有这个问题
另外ILRunTime在性能调试方面比ToLua、XLua方便的多,为什么?
因为ILRunTime的底层就是C#,所以可以直接通过Unity的性能图表Profiler看到它的内存、垃圾的开销
内存垃圾除了占用内存以外还会造成CPU的卡顿,如何优化?
这个问题的关键在于你能不能读懂它的性能图表、知不知道性能图表产生问题的原因在哪里、如何优化、和优化时有哪几种方法
ILRunTime的性能如何最大化
有同学会问:ILRunTime跟Lua的性能比究竟怎么样?
ILRUnTime不比Lua差,甚至在某些方面的性能是远远超过基于Lua的解决方案的,不管是ToLua还是XLua
至于为什么?和如何实现?可以参考我们的VIP课程
小结
![]()
游戏开发的阶段
在什么阶段要做架构
帧同步的优化要点
代码热更新的优化要点
资源热更新的优化要点
进一步学习的内容
![]()
希望大家在平时多思考一些技术问题,如果你想系统学习这里的每一个解决方案,可以考虑参加我们的课程
我想强调一点就是:做比说更重要,刚才也提到了一些问题的解决方案,但如果不亲自做一遍,是不会清楚里面的坑点的,也不能深入理解它,形成深刻印象,所以实践才是学习的要义所在
写在最后
更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源
今天的主题是《大型实时竞技网游开发之:深入架构与优化》
为什么会有这个主题呢?因为很多同学在学习游戏开发的课程时或者碰到大型网络游戏项目时,就会有这么几个问题:
不知道如何制作一个大型的游戏项目
实时竞技游戏的实时性如何表现
回合制或慢节奏的游戏里碰不到的问题会显现出来
所以今天的课程就是帮助大家解决这些问题,会讲解在开发大型实时竞技网游时该如何做,如何优化,这就是今天课程目标!
版权声明
本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源
机构介绍
优梦创客:我们的目标是帮助各位同学创作一款大家爱玩的游戏
我是今天课程的主讲老师雷蒙德,在行业内有14年的从业经验,做过程序员、技术经理、教学经理,目前的是我们优梦创客的创始人
下面是我曾经参与制作过的一些成功的项目作品,包括有:《传奇世界》,《神迹I/II》,《疯狂赛车》,《Infinity3D引擎》,《剑网三》等
主题
今天的课程主题:
游戏开发可以分成几个阶段?
在什么阶段做游戏的架构,在什么阶段要针对游戏做优化
帧同步游戏的架构有哪些地方需要优化?
代码热更新的优化要点
资源热更新的优化要点
游戏开发的阶段
游戏开发可以分成五个阶段
第一阶段:此阶段需要确定需求(开发什么样的游戏),进行预研(确定项目能不能做),然后立项(筹备资金与人才)
第二阶段:此阶段需要开发底层库和高层架构
第三阶段:开发业务逻辑
第四阶段:进行游戏测试
第五阶段:里程碑达成(阶段性目标达成,进入下一轮迭代)
注意点
没有人能预见到所有的事情
在软件开发里,唯一不变的是变换的需求
架构不是空谈
不管是在学习中还是在开发项目的过程中,都需要遵循商业项目的规律来做
《皇室战争》商业帧同步项目的开发过程
S1:项目原型开发
核心游戏系统
从零开始一步一步的实现游戏项目的核心系统,比如《皇室战争》是卡牌实时竞技游戏,那么它的特点就是:
1,离不开卡牌:需要开发卡牌系统
2,离不开卡牌的实时竞技:需要有战斗系统
基础架构支持:
一个商业项目需要有消息系统、UI框架、Shader效果、资源管理、代码热更新等架构支持
大型分布式服务器开发基础
S1里开发的主要是游戏客户端部分,但现在不是网络游戏的手机游戏可能很少了,而且单机游戏很难获得良好的收益,所以要学习开发大型分布式服务器
有同学可能会问:“我在最早开发游戏时可能没有考虑到网络问题,那么我的项目架构该怎样支持网络游戏开发呢?
在商业项目开发中,即使有一个功能现在暂时没有做,也要把它的接口留好,该留哪些接口是由自己的开发经验所决定的
在大型分布式服务器开发阶段里能学到:
分布式服务器
客户端跟服务器的通信流程
怎么样保证服务器的高性能
而且我们的服务器冗余非常小,当你把服务器的协议定义好以后,架构会直接帮你把服务器的数据库、服务器跟客户端通讯的协议生成好
S2:帧同步的客户端和服务器架构
什么叫帧同步呢?
传统的网络游戏,就是玩家发出一个操作到服务器,服务器接受到后会计算,然后传递给客户端,比如把攻击防御的结果返回给客户端,如果是移动操作,就会发送移动后的角色坐标给用户的客户端
但传统方式在游戏过程中要传输的数据量是很大的,因为服务器向玩家客户端传递的数据量就已经很大了,还要把这些数据同步给其他客户端
那该怎么办呢?
可以采用帧同步,帧同步就是当玩家执行某一个操作后发给服务器时,服务器不会做运算,会直接把这个消息广播给所有客户端
比如移动命令,玩家操作传到服务器,服务器不会做运算,而是直接把消息广播给别的客户端,它的通讯量只是你按了几个键、按了什么键而已
《王者荣耀》就是采用帧同步来实现战斗的,所以《王者荣耀》的实时性和打击感做得很好。这是什么原理呢?
因为它把所有的运算都放在游戏客户端,这时服务器的性能瓶颈就只有它的数据传输能力和转发能力
这是帧同步架构服务器的能力要求,我们的项目需要能够适应这样的服务器架构
做完服务器架构设计和功能实现以后,还需要机器人压力测试,我们的服务器是能够明确支持万人同服的,这不是玩具代码所能够实现的功能,而是一个真正的商业项目架构
一个玩具项目就是写完数据库的协议、还要写网络协议、序列化协议、没有数据缓存,也没有实时竞技的元素,那么这个项目的难度、对学习能力的锻炼、通过实战项目锻炼的价值就没有那么高
帧同步的难点在哪里呢?为什么说帧同步游戏是一个实时竞技游戏呢?
我用《皇室战争》项目举个例子:
我出了一张卡牌,在这张卡牌变成游戏单位行动时,它是由你来控制的吗?不,它是由游戏的AI来控制技能释放、进行战斗的
所以它的游戏AI系统会非常复杂,而且由于所有的运算都是每一帧实时运算的,你在开发那些慢节奏游戏时碰不到的问题都会在实时竞技游戏里暴露出来,你在实时竞技游戏中所得到的锻炼跟传统的回合制游戏也是不一样的
而且帧同步有很多开发要点,客户端有很多坑点和可以对你形成经验的点,一些同学只是学习了S1加S2包括前面后面的一些基础知识和后面的面试准备,就能使面试官对他刮目相看
S3:双端热更新
前面的S1课程已经实现了代码热更新,但S1中的代码热更只是在客户端中进行热更,在S3里会再次深入代码热更新,学习客户端热更和服务器热更
有同学可能会说:服务器要热更新干什么?
如果你有一个大型的游戏项目,而这个项目经常需要停服热更的话,那这对游戏公司的运营损失是很大的
而且当出现一些小bug或者一些比较严重的bug时,当前又暂时不能停服时,就可以实现服务器的实时热更新来解决这个问题
当然了,实时热更新不是直接在生产服务器上更新,而是会先在开发服务器上测试,测试通过以后才会把它更新到支持热更新的服务器上
客户端热更部分
ILRunTime能够很好的支持客户端的热更新,并且不需要学另外一门编程语言
传统热更新是用Lua来做的,我们之前的课程也是用Lua来做热更新,另外我们的Lua课程讲的也是非常不错的,我们从基本的使用到Lua在ToLua、XLua中使用、它的底层原理、性能瓶颈点、源码实现、Lua跟C#的脚本绑定、GC的开销、方方面面都对它做了系统的分析
不管是用ToLua、XLua、还是用ILRunTime,都需要对底层原理进行学习,如果不学习底层原理,那要怎样理解它的优化方式呢?怎样把这个东西用好呢?
所以S3阶段不是针对某一项技术,而是要学习方法,理解它们的原理
S4:发现问题,解决问题,项目迭代
将学完S1课程后就能够面试客户端开发;S1、S2学完能够高薪入行;如果你是有经验的开发者,想要进一步提升,那么建议将学完S2加S3,并且要对S2和S3的内容有充分的理解
老师也会在笔试、面试模拟环节帮助大家进一步巩固知识,提升对知识的理解,当然还有其他方式也能帮助大家理解知识,比如一对一指导和每周直播
S1到S3实际上就是从原型开发到项目架构到具体功能实现的过程(也包括了项目的迭代),到S4以后就相当于商业项目进入了后期
在这个过程中可能会发现有各种各样的问题,如果你平时只是做UI、做逻辑、接SDK,你可能发现不了这些问题,因为这些问题都是我们从规模、架构、底层实现的角度提炼出的,我们也会教大家如何解决这些问题
大家如果想知道我们在S4课程里是如何发现问题、解决问题、做项目迭代的话,可以在文末加一下爱丽丝老师来了解课程详情
架构优化
1,退出战斗或游戏时报错
这是很多同学在开发小型游戏时,想要退出战斗或退出整个游戏项目时会出现的问题
如果你开发的是小游戏,那这个问题不会太明显,因为游戏对象比较少,要处理的数据量也少
但如果你的对象多一点,问题就会很明显,这个问题是怎么造成的呢?
举个例子:有A、B、C、3个GameObject,每个GameObject上都挂了相同类型的组件,每个组件上都有一个Start方法
那么你能告诉我这3个对象是哪个先Start,哪个后Start吗?它可能第一次执行时是A的Start,然后是B,最后是C;第二次启动时可能是B先执行,第三次可能是C先执行
所以它们的顺序是不确定的,那么再假设这三个对象之间有一些依赖关系,比如B中有一个X字段,A初始化的Start方法里有一个Y字段,它是X的平方
那如果现在程序的启动顺序是B先启动,然后A再启动,那么这没有什么问题,但是如果反过来呢?是A先启动,然后B再启动,这样Y就获取不到有效X的值,程序就会报错了
这是程序启动时会碰到的问题,那么在退出时是不是也会遇到一样的问题呢?答案是当然的,想要解决这个问题就需要自己管理程序的生命周期
2,如何管理多次出现或数量较多的对象
举个例子:
有一个角色实体,角色头顶上有一个血条实体,角色身上还有一个挂件实体,血条有自己的属性数值,挂件也有自己的属性数值,那要怎样管理角色实体,以及角色实体身上的血条和挂件呢?
从位置关系上来看这个实体:
血条要跟着实体走,所以它们是父子关系
从数据管理的角度上来看:
血条和挂件是角色实体的一部分
具体要怎么管理,大家可以自己想一想,把你们认为对的答案发在评论区
3,异步性能太低,协程太分散,该如何管理
有些同学会在程序里大量使用协程或者异步,但不管是协程还是异步,都是由CLR框架管理的,并且不管是Lua,还是ILRunTime,它都是一种程序脚本
既然是脚本,那就是有脚本层调用开销的,这就存在性能问题,那么这个性能问题该怎么解决呢?
很多时候我们使用异步主要就是两个目的
1,延时
2,资源的异步加载
如果能解决这两种异步产生的问题就可以取得更好的性能效果
另外还有一个问题就是:如果使用协程呢?
因为异步底层也是CLR通过协程来实现的,如果程序里过多的使用了异步或者协程,那么对CLR的管理开销是比较大的
这就好比在程序中创建了很多的线程,线程的好处是可以一起干活,而多线程的坏处也正是它的好处带来的,因为线程本身带来的开销就是很大的,线程调度带来的开销也是很大的
这就是架构要优化的点,它会出现难以管理的问题,而我们的项目已经把这些问题都解决掉了,所以它跟你自己做着玩的项目是不一样的
4,异步的流程管理
使用异步就会存在一个问题:异步程序会产生很多不能确定在什么时机执行的程序流程
因为异步程序不是在这一帧就启动的,它是在另外一帧或者另外很多帧以后才去执行,而且是定时执行的,不像同步程序,执行顺序很明确
所以异步不便于管理,但有时又不得不使用异步,这就存在一个问题:能不能在不需要用异步时把它同步化
这是要从程序的结构上来做的优化点,如果能实现会带来很多好处
1,可以提高程序性能
2,可以让程序更加稳定
但有时可能不得不用到异步,这其实也是可以优化的,比如下面的问题
5,卡牌”变兵“时的卡顿
这是我们在开发《皇室战争》时碰到的问题:
战斗时的每个兵种、每种卡牌,在第一次放到场景中变成游戏单位时都会稍微卡一下
如果你是一个有经验的开发者,那你一定会碰到测试跟你说这样的问题,而且这是一个非常高频的面试考点,该怎么解决呢?
就是使用对象池,但因为对象池本身也是有使用开销的,使用不当就会在战斗过程中造成更大的卡顿,因为对象池的原理是:
当对象不够时就会创建新对象
所以在战斗时创建对象就会造成卡顿,这在我们的项目中有相应的解决方案
6,对象池中的对象随着战斗单位的增多而膨胀
比如对象池里原本有五个对象,那当这五个对象不够用时有什么处理方法呢?
直接实例化一个新的对象,但它可能会卡顿,特别是战斗的时候
那么应该怎样避免在战斗时实例化造成卡顿呢?而且不停的实例化对象也会造成对象池的膨胀
比如一局战斗中用到了50个对象,这些对象都是从对象池里取出来的,所以对象池里就必须要保证要有50个对象,也就是要实例化50个对象,那么在这局游戏进行的过程中要增加对象或者这局游戏结束了,对象池里的对象不用了,该怎么办呢?
这牵涉到了Mono的内存管理问题,会在我们的课程里教给大家
7,对象池扩容卡顿
8,UI模块逻辑多了难以维护
如果你的UI很简单,只有10行20行代码,或者100行代码,那就不用担心这个问题
但如果有200或者300行代码,甚至是四五百行代码,那你就要注意怎样解耦了
AA的优化
如何最大化利用AA资源管理的优势
Addressable也是可以优化的,先给大家介绍一下AA的能力:
使用AA可以在一小时以内做完资源热更新功能,传统的AssetBundle方式是不可能达到这种效率的
因为仅仅只是AssetBundle的打包策略选择、打包功能定制、打包工具编写就得花一两天,对于新手可能要一个礼拜,而且资源的释放问题也需要自己处理
但AA只需要遵守AA的编程规范就不会犯错,所以AA很简单,但要把AA用好还需要对AA有更深入的理解,需要掌握AA的底层机制,包括面板上每一个选项的含义
AA能实现自动打包吗?
可以
AA能定制打包规则吗?
要针对AA来实现打包规则定制需要对AA非常熟悉
AA资源冗余能否优化
AA本身比AB(AssetBundle)好的地方就是它的功能拓展,可以通过功能扩展来实现资源冗余的优化
我们的框架对AA本身提出的资源冗余检测和优化方案做了进一步的升级,成为了第二代的资源优化方案
关于什么是资源冗余优化,可以看我之前的关于资源热更新的公开课
AA怎样做到下载时全部更新完毕再进游戏?如何显示下载进度?
AA默认的方式就是资源随用随更新,比如角色模型发生了变化,那么当游戏加载时,AA就会下载这个资源
但这种方式有个缺点:如果在战斗时加载这个模型就会造成程序的卡顿
怎样能做到下载时全部更新完再进游戏呢?
这需要对Addressable的底层的API机制非常熟悉,并且要实现一套完整无错的解决方案
这样就可以下载全部资源再进游戏,并且能显示下载进度
AA远程下载的缓存机制是是什么样的
什么叫缓存机制?
当远程下载的资源过多,不能一次下载完时,就要考虑到:如果资源在下载的过程中断网、或者因为信号不好而下载中断了,那么是要重新把资源下载一次吗?AA会重新下载资源吗?如果要重新下载资源,那怎样最小化资源的下载量呢?这都是商业游戏项目需要考虑的
如何打包才能达到资源更新的最小开销,并且能够合理的验证资源的版本是否更新?
需要理解一些AA的打包优化策略
ILRunTime优化
游戏战斗过程中,游戏单位增多时GC开销比较大,CPU运行卡顿
这个问题无关使用ILRunTime还是用ToLua,它们都会有这个问题
另外ILRunTime在性能调试方面比ToLua、XLua方便的多,为什么?
因为ILRunTime的底层就是C#,所以可以直接通过Unity的性能图表Profiler看到它的内存、垃圾的开销
内存垃圾除了占用内存以外还会造成CPU的卡顿,如何优化?
这个问题的关键在于你能不能读懂它的性能图表、知不知道性能图表产生问题的原因在哪里、如何优化、和优化时有哪几种方法
ILRunTime的性能如何最大化
有同学会问:ILRunTime跟Lua的性能比究竟怎么样?
ILRUnTime不比Lua差,甚至在某些方面的性能是远远超过基于Lua的解决方案的,不管是ToLua还是XLua
至于为什么?和如何实现?可以参考我们的VIP课程
小结
游戏开发的阶段
在什么阶段要做架构
帧同步的优化要点
代码热更新的优化要点
资源热更新的优化要点
进一步学习的内容
希望大家在平时多思考一些技术问题,如果你想系统学习这里的每一个解决方案,可以考虑参加我们的课程
我想强调一点就是:做比说更重要,刚才也提到了一些问题的解决方案,但如果不亲自做一遍,是不会清楚里面的坑点的,也不能深入理解它,形成深刻印象,所以实践才是学习的要义所在
写在最后
更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源