Unity 千人战斗玩法

我要开发同款
啊克ca2023年03月03日
327阅读
所属分类C#Unity

作品详情

这是一个实时战斗的战争玩法,小兵的数量我们计划是1000个单位,多兵种,每个兵种有自己特有的AI和技能。这个玩法类似莉莉丝的《剑与家园》。我在该玩法的开发中完成超过90%的功能,主要涉及基础框架代码,兵种AI,技能和buffer以及相关的性能优化。

基础框架: 主要包含项目开发的通用模块,Unity Asset的加载和释放的管理,网络,UI的管理以及相关规范制定,缓存的管理方案以及一些规范类的文档编写。

AI: AI部分就是小兵的寻路部分,这部分的性能消耗最大的是物理碰撞和寻路算法。因为要做录像功能,所以我们不能使用Unity自带的寻路和碰撞。一方面是两部分因为API的原因很难集成到我们逻辑计算里,另一方面它们的运算都是基于浮点数,在播放录像时会出现结果不稳定的情况。所以我自己单独实现了一套圆形的碰撞而技术核心是用四叉树就解决碰撞的性能问题。另一方用跳点算法代替A星算法加速了寻路速度。而AI部分我们则是用阵型AI叠加小兵单独AI的模式,避免了N*N的算法复杂度。最后我们实现了一套通用的AI和扩展了每套小兵可能有的独立AI。

技能和buffer: 技能这块主要是一些编程技巧,我将技能需要的指令原子化,比如移动,等待时间,造成一次伤害,添加buff等。然后再实现一套定时器(原因也是录像功能),将定时器和指令结合生成一个技能管理器和buff管理器,用来定时触发指令。buffer还会有自己独立的触发时机。因为编程部分已经实现指令化,所以我再实现了配置表处理一些通用技能的同时,又将指令封装成API对接Lua后,可以用相对Lua快速的开发。但是我们没有实现编辑器是因为开发周期不允许,各自个人是有一套这套编辑的构想。

CPU性能优化: 因为是CPU计算非常密集的玩法,所以数据结构上我没有使用List而是直接使用Array,尽量避免Dictionary。避免使用C#的语法糖,比如foreach等。一开始我会尽量去优化寻路算法,用缓冲池管理单帧的寻路次数。但是这样在大量数量的小兵时,会出现很多小兵“发呆的情况”。后来我用多线程去解决这个问题,但是因为需要实现录像功能,所以这里会有些限制且需要两套完全独立的数据在主线程和子线程。首先我将计算量最大的AI放到子线程,限定每0.5秒一个回合,每回合向子线程请求一次AI计算,等计算完毕返回后,开始计算技能(这里不一起放到子线程是因为节能对接了Lua,Lua是单线程的),然后开始表现。这里为了解决多份数据的问题,我单独生成了一份表现数据,用来在主线来做图像的表现(该数据类似: A模型做一个Idle动作,A模型从a位置移动到b位置等)。这样主线程只负责表现,而表现数据的生成则有子线程的AI和主线程技能完成。

GPU性能优化: 这部分的优化主要来自绘制1000单位的压力。正常我们直接使用Unity自带的Animator的话,基本300个就卡的不行了,原因是模型的动画计算已经将CPU卡死。所以我们想到将动画计算移动到GPU上。为了降低实现的复杂度,我们最终没有完成蒙皮的移植,原因是小兵太小确实也不需要,而针对首领这样的大型单位我们直接使用Animator,数量也不多。所以我们将动画部分的数据记录到贴图上,然后使用GPU Instance去实现大量小兵的绘制,绘制的数据来自于战斗本身的小兵的数据和表现数据(位置,模型ID,当前动画等)。

文档规范的编写: 这部分主要是为了规范资源命名和工作流程。
声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论