《乡村铁路》开发日志3-三周目

过去的整理和总结

自从18年刚开始有这个想法到现在已经差不多两年半了,然而连一个Demo都没拿出来😂总结了一下,项目的进程大概分为了三个阶段:

一周目

18年5月,决定自己做一个模拟经营类的游戏。最初的想法是用尽量新的酷炫的技术来开发,当时Unity的DOTS刚出来(当时还没有DOTS这个名字),简单了解了下发现ECS的设计模式很适合于模拟经营(我设想的方向是类似《监狱工程师》这种场景种同时存在着大量单位在运动的感觉,而不是《边缘世界(Rimworld)》这种只有少量角色但每个角色的行为都有精密的设计,总之就是“大规模”)。当时已经有Entitas这个第三方的UnityECS框架了,不过既然Unity官方在推,即使还是早期预览版,我还是对官方框架的前景非常看好的。

18年5月到11月,平时工作也比较忙,也没啥时间做项目,所以进度推进还是很慢。然后最致命的是,Entities库在早期的更新频率非常快,API的变更也非常快,经常过一个月更新一下新版发现各种API都改名了或者直接取消了,写起来就很痛苦。

这倒不是Unity的锅,人家在论坛里一开始就强调过,现在还处于早期预览阶段,对于某种需求,目前存在着多种实现方式。官方会观察各位开发者的反馈,最终只会留下一种方式,其他的会被取消(在这里有持续讨论有关API的易用性)。

再加上ECS的配套功能非常缺乏,而且思维还没来得及转换到面向数据的设计思想,进度推进就更慢了。

二周目

18年11月,API暂时稳定下来了,考虑到之前的设计一塌糊涂,就开了个新工程从头开始(没错,今天这已经是第二次从头开始了/doge)。

这次把之前做独立游戏时候的公共代码完全提了出来,成为一个单独的程序集。到后来改成了利用Unity的package功能,把Framework相关的代码放到了单独的git仓库(这部分是在GitHub上开源的),以UnityPackage的方式引入实际的游戏工程,避免具体业务逻辑代码污染到公共代码(这部分公共代码也陪我参加了两次GameJam😊)。

框架完善,稳步推进

19年8月,换了新的工作,变得更忙了orz。。就这么搁置到了20年2月份,疫情在家工作,这才又重新捡起来。这段时间主要把Framework部分的代码重新整理并加了一大堆新的功能。具体游戏业务也断断续续把AI框架和建造流程做完了,事情似乎变得顺利了起来,直到我在渲染方面遇到了各种奇奇怪怪的问题。

DOTS框架下的渲染主要依赖HybridRenderer这个模块,截至目前最新的版本是0.10.0-preview.21。在这个模块里官方提供了两种实现,V1和V2。我发现如果使用V1的话,似乎不能很好的支持MaterialProperty,于是我切换到了V2,发现根本渲染不出东西来😂

经过多次测试,我发现只有URP内置的Lit材质才能够正常工作,其他材质比如SimpleLit或者任何用ShaderGraph做的自定义材质,在转换成Entity之后均不能正常渲染。

fig1

如图所示,空白场景种有三个球,从右往左第一个是正常方式渲染,第二是使用Lit材质并转换为Entity,第三个使用默认ShaderGraph创建自定义材质并转换为Entity。运行起来会发现最左边的不见了,中间和右边的还在:

fig2

最诡异的是在FrameDebugger里是能看到对应的DrawCall的,但是什么也没有渲染出来。经过在官网论坛的求助,我发现如果开启了SRP Batcher,模型就可以被正确渲染了,但是我当时为什么要关掉SRP Batcher呢,因为开启之后环境光信息会丢失。。这篇帖子上有人在讨论,至少到现在还没有一个完美的解决方案,Sad。

新的计划

考虑到DOTS目前还不是很成熟,面向数据的思维也不是那么容易一步到位就转换过去的,我最终还是决定重新基于传统面向对象的方式来开发整个游戏,但是会在其中适合并行计算或者计算内容简单但是量大的地方去使用JobSystem和BurstCompiler这两个模块。这样的话开发起来会比较顺手。。应该。

一些暂时能想起来的细节

  • 整个场景依然基于地块,设计尺寸为100x100,每个地块一个struct,数据以NativeArray来存储以保证最快的存取速度

  • AI之前想着用Goap来做,但感觉如果Agent数量太大,Goap的计算压力会有些大,反正我们对单个AI的智能程度要求不高,待在原地傻站一会等待思考也是完全没有问题的

  • 关于寻路,还是用跟之前一样的方案,每个地块上的实时拥挤程度会被寻路过程考虑,AI寻路结果会避开人太多的路口,显得自然

  • 地块,角色,装饰物的渲染可以采用类似BatchRendererGroup的方式直接渲染,避免大量的GameObject.Instantiate开销,可交互的逻辑物件(数量会少很多)采用传统MeshRenderer来做,方便调试

  • 使用数据中心机制,可以整体对所有运行时数据做快照,方便保存和加载(需要考虑如何解决版本间兼容问题)

总结

今年年初的时候有立了一个Flag说过年之前至少要搞出个最小可玩的Demo版本,距离这个期限只有两个多月了,不知道换了方向之后能不能赶上😂