Unity网游开发生存指南—蒸汽之城
前段时间关于Unity是否适合国内手游/网游创业团队的讨论非常火爆,本文从《蒸汽之城》的开发历程谈起,对于国内网游团队是否应该选择Unity引擎,以及如何解决使用Unity开发网游时遇到的各种主要问题进行讨论。
厦门梦加的蒸汽之城
《蒸汽之城》是厦门梦加网络的第一款作品,使用Unity引擎制作的蒸汽朋克风3D实时战斗MMORPG页游。游戏拥有幻想工业时代恢弘苍凉的场景;丰富的种族、职业和技能系统;和端游比也毫不逊色的优质画面和特效;各式各样的副本挑战和PvP活动;最后,所有这一切用户都能直接在浏览器中以极短的下载时间享受到。《蒸汽之城》被包括福布斯、Massively、ZAM等知名媒体列为2013年最值得期待的MMORPG游戏之一,目前已经签约了多家海外发行商,范围覆盖所有英语国家、东欧、土耳其和中东。土耳其版本已经于3月1日(北京时间)正式开始公开测试。
梦加团队当初选择Unity引擎的原因和大部分团队类似,快速出原型、大量现成的内置功能和中间件、支持在浏览器里展示高素质的3D游戏画面。在几年的开发过程中团队才慢慢认识到用Unity开发MMO页游需要克服太多问题和陷阱。幸运的是我们最终克服了绝大部分问题,《蒸汽之城》也即将开始海外公测。下面我们会深入探讨要完成一个高素质的Unity页游MMO,应该解决哪些技术问题和怎样建设团队。
请注意,这里我们不会讨论使用Unity制作单机游戏,因为Unity单机或者有社交功能的手游都有太多成功的巨无霸例子,很多开发者也通过自身经验表明小团队使用Unity制作轻量级的单机或社交游戏并无太大障碍,下面我们还是以多人在线,需要后台和大量数据处理的MMORPG为例来讨论。虽然梦加到目前为止都一直在开发浏览器版本的游戏,但其中很多技术话题对于多人手游项目也同样适用。
从传统页游到次世代技术
虽然Unity已经有了7年多的历史,这款引擎从诞生之初就一直保持了比较先进的设计理念,包括其一直以来的首要卖点:为开发者提供基于浏览器的高素质3D游戏解决方案。Unity的特色既包括面向独立开发者的快速原型、低成本跨平台发布,也在近年来整合了更多高端商用的中间件和次世代的渲染技术。使用Unity现在已经可以开发素质几乎达到用Unreal Engine、CryEngine这些次世代引擎开发的游戏,Unity也被越来越多的AAA工作室选用来开发跨平台的主机游戏。
这意味着Unity很好很强大,没错,但不代表团队选择Unity就是理所当然的。商用引擎的一大特点是兼容并包,要适合各种不同的项目和团队需要,而作为次世代引擎,其中又包括了大量图像、动画和资源管理的先进技术。对于初创团队来说,选择Unity虽然得到了一大堆可以快速见效的功能,但面对这些功能时如何取舍,以及对引擎技术的理解和挖掘程度,都会对项目的命运造成决定性的影响。
Unity虽然一直以易上手、原型快速、中间件丰富整合快速著称,但随着项目规模和复杂程度的上升,很快开发团队就会进入一块网上各种单机游戏教程无法涵盖的真空地带,而国内网游技术分享的环境又相对比较薄弱,这时在一些关键的技术难题上,初创团队就会遇到很大的麻烦。从快速原型到攻克大规模项目的技术难题之间,通常是让很多团队无法正确估计成本的危险过渡地带。这也是很多使用Unity的项目结果反而不如使用自主开发的引擎或相对老旧引擎的原因。自主引擎任何功能都要自己开发,相对老旧的引擎功能较为局限,所以在内容和功能规模方面的计划一般不会太过狂放;而Unity这样的引擎包括从官方和社区的宣传上都给人一种到处都是随手可得的免费午餐的感觉,反而会让团队的计划更加激进,对困难认识不足。
下文中我们会对这些危险和解决方案进行逐一的分析,希望能给经验不足的团队提供警示和提前准备好解决问题的思路。
内容规模和版本控制
开发者在不同类型和规模项目的经验,很大程度上造成了对”Unity是否适合手游/页游创业团队“这一讨论两极分化的看法。对于以《Temple Run》、《亡灵杀手》等游戏为榜样的单机游戏开发者,以及CSR Racing这样有多人对战模式的单机游戏,即使团队很小使用Unity开发都不会遇到什么太大的问题。这些单机游戏非常适合发挥Unity游戏性成型快的优势,而内购、社交等功能都可以用现成的中间件来快速实现。
当使用Unity制作有海量内容的网游时,团队遇到的第一个问题,就是无法把游戏的全部内容放进一个Unity项目中。一方面资源文件数量达到一定程度后,每次开启项目的导入过程就够你泡壶茶;另外几十人的团队共用一个项目,在版本控制和数据安全性方面也会有很大的危险,任何人的操作失误都可能导致整个项目瘫痪;最后不同分工的开发者需要面对的项目数据和工作流程差别很大,共用同一个项目会在很大程度上降低生产效率。
《蒸汽之城》使用了很多个Unity项目来为各个不同的部门和小组提供定制的数据范围,工具和流程。3D角色美术的项目里只使用角色数据(FBX->Prefab)和相关的预览和打包工具;场景美术使用不同的项目来管理不同的场景;客户端程序员使用的是主要的客户端项目,他们的代码运行后可以读取其他开发者上传到服务器上的数据,从而让游戏跑起来。而大部分开发者可以使用编译成可执行文件的客户端来测试自己随时向测试服务器上上传的资源和设计数据,从而既保证了每个人能最高效在自己的领域里工作,又保证了自己生产的内容能够随时在游戏版本中测试。
如此多的项目要怎样实现版本控制呢?我们的解决方案是用Gitlab作为统一的管理平台,每个项目作为一个单独的Git Repository(仓库)。使用Git的最大优势在于客户端项目的版本管理,客户端项目随时都有多名程序员在提交代码,使用Git就能让他们把测试代码和稳定代码通过不同分支(Branch)来管理。我们使用master分支作为稳定的版本,来合并每个程序员提交并测试通过的个人测试分支;整个团队使用的可执行客户端用master分支来编译创建,就保证了新功能开发的速度和主版本的稳定性。
另一个优势在于Submodule的使用,通过Git的submodule功能我们可以在不同项目中共享一份核心的底层代码和部分工具代码,这样就不用为每个项目分别进行游戏引擎和工具更新。Git作为目前最先进的分布式版本控制系统,在掌握难度上是非常高的。国内网游团队即使是程序部门使用Git作为版本控制系统的情况也不是太多,而梦加做到整个团队都用Git作为日常的版本控制系统,付出的努力虽高,但回报绝对物有所值。
数据处理和工具开发
近期的讨论中很多人认为Unity的短板之一在于偏重代码驱动的引擎没有办法处理大批量的数据,这种印象可能跟官方和社区对于那个运行超级方便、什么工作都能往里放的MonoBehavior类的大力宣传和依赖有关。实际上Unity里除了MonoBehavior还有使用.NET标准的自定义类,有用法非常灵活的统一数据类型scriptableObject,还有各种各样只有你想不到没有你做不到的编辑器脚本和数据处理接口。只不过除了MonoBehavior,其他一切数据处理手段都需要开发者去Unity的官方论坛和StackOverflow这样的泛编程问答站点深入挖据。官方论坛上通过搜索,其实是能找到很多使用Unity做大数据量网游的同行讨论的,只不过这样的引擎在国内还没有形成很大规模的知识分享社区,一些做的比较久的中文Unity论坛也缺乏网游项目的讨论,所以给人的印象就是Unity不擅长做这个。
事实上,Unity处理各种数据类型(XML,Json,SQL)都有现成的接口(用户提供和分享的开源代码),而《蒸汽之城》策划团队日常使用Excel格式的数据配置,也可以很容易的转化成XML后通过编辑器脚本导入Unity。最后客户端只要读取和处理导入后的scriptableObject就可以了,一些改动频繁的数据还可以直接使用XML格式在运行时读取,减少客户端需要更新的频率。
说到数据处理使用的编辑器脚本,这里就必须要探讨工具链开发的问题。对于任何大型项目,开发配套工具都是至关重要的,Unity的特色在于编辑器本身有着非常优秀的可扩展性,所以我们使用的工具链包括编辑器脚本和外部工具两部分,分别用来处理客户端和服务器端需要的数据。比如任务逻辑和对话的编辑器是直接编辑数据库的,所以我们使用VC制作的外部编辑工具。而包括关卡、资源导入、贴图合并、NPC角色打包等等要处理Unity使用的资源数据的工具,都是使用Unity脚本制作,开发者通过菜单命令就可以快速完成资源管线操作和编辑。
一款数据量很大的网游在工具开发和维护方面需要投入的力量是很大的,《蒸汽之城》在增加了工具开发的人手后,其他开发和资源生产部门的工作效率都得到了显著的提升。此外通过不断改善工具的可用性,加入大量对用户操作的预先检定,可以有效的减少操作失误造成的数据错误,提高了游戏版本的稳定性。
原型碎片和整合测试环境
上面提到Unity里能驱动一切的MonoBehavior类为原型开发提供了很大的方便,但作为网游项目,任何功能和资源都需要在游戏实际联网运行环境下进行测试。如何在Unity网游项目中平衡原型开发和实际联网测试呢?项目早期基础功能的原型,包括动画系统、图像渲染、角色换装等等,都是可以直接建立单机原型的。用脚本实现基本功能后再加上编辑器脚本和GUI脚本来为测试加上配套工具,然后再交给资源生产部门来添加游戏中的资源。
地下城、任务和战斗系统因为涉及到很多和服务器端的通讯部分,如果需要测试就必须使用一个支持最简单的客户端服务端架构的单元测试档案配置。这里所说的档案,就是定义了你全部测试内容数据(或者去哪里找这些数据)的scriptableObject。包括你用来测试的帐号、角色信息、测试场景、任务或技能配置等等。以主城和地下城为游戏内容载体的《蒸汽之城》里,我们也制作大量测试用的地下城或主城场景作为任务和新功能生产的测试环境。测试环境由美术或策划来制作,然后交给程序部门来测试代码,最后再交给QA测试刚完成的功能。
Unity的强大原型制作能力主要还是应该体现在项目初期。一旦客户端服务端架构形成,可以在稳定的服务器环境上运行游戏以后,开发团队就应该把更多的精力集中在如何能够在实际服务器上快速添加新内容并进行测试。《蒸汽之城》有过三组测试服务器,分别用来进行代码、资源和网页接口的测试;此外对于需要频繁更新调整数据的任务策划和关卡设计人员,他们会使用在个人电脑上架设的服务器,来避免数据更新对其他人测试带来的干扰。
动态下载和读取
对于网页游戏来说,如果不能做到快速启动和最小化下载等待时间,相对于端游的优势就不存在了。《蒸汽之城》里所有美术资源都被拆分成了非常小的零件,这样用户只要下载一次,就可以在运行游戏时根据需要来动态组合,大量减少了资源的重复下载率。而地下城制作的时候会使用工具进行Serilization,游戏时每个地下城只需要下载一份XML表单,然后就会自动从用户已经下载的“资源零件”中寻找需要的部分并进行动态拼装。体验过《蒸汽之城》的用户可以发现任何地下城的读取都不会超过数秒。
接下来说说Unity页游的一大招牌Asset Bundle的使用。Asset Bundle是可以被用户stream下载的资源包,其中可以包含任何Unity Project中的文件。要做到动态下载,游戏中的绝大部分资源就都必须打包成Asset Bundle才能使用。在《蒸汽之城》的开发过程中,我们为大部分资源生产者制作了Unity编辑器内的打包工具,只要选择相应的菜单命令就能自动完成打包和上传到测试服务器上。在以后的项目中我们希望能采用Resource.Load()和Asset Bundle结合的方式,客户端可以分别读取原始的资源文件来使调试更方便,而测试通过后又可以切换成使用Asset Bundle来保证游戏的动态下载正常运行。Asset Bundle还有很多创意用法,大家可以看看官网上Unite2012的相关讲座。
技术导向的团队建设
前面提到了Unity在项目规模和复杂程度从单机到网游的巨大增加,可以说如果对于国内大部分团队,使用Unity制作网游都有着一定的风险和挑战。简单的说,Unity对于单机游戏来说,确实有很多“免费附加值”可以用来快速搭建项目和完善产品功能,但在网游或较大型项目层面,如果没有对于项目质量的较高要求,没有一个好的团队技术氛围和建设思路,选择Unity得到的免费回报和付出的技术建设成本实际是得不偿失的。
假如看官读到这里还对于使用Unity坚定不移,可以看看下面对于如何建设Unity适用型技术团队的一些建议。
但作为网游项目,任何功能和资源都需要在游戏实际联网运行环境下进行测试。如何在Unity网游项目中平衡原型开发和实际联网测试呢?项目早期基础功能的原型,包括动画系统、图像渲染、角色换装等等,都是可以直接建立单机原型的。用脚本实现基本功能后再加上编辑器脚本和GUI脚本来为测试加上配套工具,然后再交给资源生产部门来添加游戏中的资源。
地下城、任务和战斗系统因为涉及到很多和服务器端的通讯部分,如果需要测试就必须使用一个支持最简单的客户端服务端架构的单元测试档案配置。这里所说的档案,就是定义了你全部测试内容数据(或者去哪里找这些数据)的scriptableObject。包括你用来测试的帐号、角色信息、测试场景、任务或技能配置等等。以主城和地下城为游戏内容载体的《蒸汽之城》里,我们也制作大量测试用的地下城或主城场景作为任务和新功能生产的测试环境。测试环境由美术或策划来制作,然后交给程序部门来测试代码,最后再交给QA测试刚完成的功能。
Unity的强大原型制作能力主要还是应该体现在项目初期。一旦客户端服务端架构形成,可以在稳定的服务器环境上运行游戏以后,开发团队就应该把更多的精力集中在如何能够在实际服务器上快速添加新内容并进行测试。《蒸汽之城》有过三组测试服务器,分别用来进行代码、资源和网页接口的测试;此外对于需要频繁更新调整数据的任务策划和关卡设计人员,他们会使用在个人电脑上架设的服务器,来避免数据更新对其他人测试带来的干扰。
首先,团队项目负责人和技术骨干关注Unity官方发布的信息和社区技术热点讨论是必须的。比如说从Unity4开始就可以在手游上使用动态字体和动态阴影了,而这些消息的发布是在去年夏天的Unite前后,一直关注Unity新技术的团队就可以为项目提前做好特性计划。而且Unite上大量非常有价值的官方和开发者讲座,也能弥补很多官方教程和手册中没有涉及的空白区域,恰好是国内网游团队急需的(比如Asset Bundle使用讲座,Network基础讲座等等)。另外一个非常重要的知识库是Unity的官方论坛(http://forum.Unity3d.com )和问答社区(http://answers.Unity3d.com ),这两个社区站由官方技术人员和活跃的。
Unity用户共同提供内容和维护。配合Google搜索,你几乎可以在这些社区网站上找到任何技术难题的答案,而且还会有各种实际案例的解决过程(因为提问的人很可能和你有着同样的问题)。当然使用这些官方社区必须要有较好的英语阅读能力,这本身就对技术团队的素质有了一定的要求。国内的Unity社区和资讯网站也在越做越好,其中像Unity圣典(http://game.ceeger.com/forum/ )和Unity教程手册系列(http://www.Unitymanual.com/ )都是不错的资源入口,建议英文不够熟练的朋友以这些中文网站为索引,慢慢将获取知识的渠道扩展到国外网站。
第二,Unity项目要形成有规律的从原型代码到结构化的重构的循环过程。Unity做原型快,又有很多现成的解决方案,在开发周期紧张的情况下,开发者很容易会不断添加快速完成的功能,最后让项目的结构臃肿不堪,内容扩展到一定程度就会遭遇新功能添加的瓶颈。也就是说,如果没有周期化的重构,项目功能扩展到一定程度后,再添加新功能或调整原有功能,其成本都会成倍上升。而太过频繁的重构又会影响项目进度,如何把握这个度,就要根据团队人员的结构来精心安排了。
第三,Unity大型项目非常适合从早期就规划好完整的工具链,根据不同开发者的技能和使用习惯定制不同的工具。对于个人开发者来说,Unity里有大量的中间件可以满足不同技术水平用户的需要。在网游团队中也可以用相同的思路来提高效率,应该尽量避免只有程序员使用Unity,美术和资源生产都只局限在其他外部工具里的生产环境。另外工具链的功能扩展和完善是一个长期动态的过程,根据项目在不同阶段的状态,对于工具需求的变化是非常正常的。建议团队从一开始就安排足够的人手开发工具,并且将工具维护和需求收集作为日常工作流程的一部分看待。
后4.0时代特性展望
Unity适用型技术团队的一些建议。
但作为网游项目,任何功能和资源都需要在游戏实际联网运行环境下进行测试。如何在Unity网游项目中平衡原型开发和实际联网测试呢?项目早期基础功能的原型,包括动画系统、图像渲染、角色换装等等,都是可以直接建立单机原型的。用脚本实现基本功能后再加上编辑器脚本和GUI脚本来为测试加上配套工具,然后再交给资源生产部门来添加游戏中的资源。
地下城、任务和战斗系统因为涉及到很多和服务器端的通讯部分,如果需要测试就必须使用一个支持最简单的客户端服务端架构的单元测试档案配置。这里所说的档案,就是定义了你全部测试内容数据(或者去哪里找这些数据)的scriptableObject。包括你用来测试的帐号、角色信息、测试场景、任务或技能配置等等。以主城和地下城为游戏内容载体的《蒸汽之城》里,我们也制作大量测试用的地下城或主城场景作为任务和新功能生产的测试环境。测试环境由美术或策划来制作,然后交给程序部门来测试代码,最后再交给QA测试刚完成的功能。
Unity的强大原型制作能力主要还是应该体现在项目初期。一旦客户端服务端架构形成,可以在稳定的服务器环境上运行游戏以后,开发团队就应该把更多的精力集中在如何能够在实际服务器上快速添加新内容并进行测试。《蒸汽之城》有过三组测试服务器,分别用来进行代码、资源和网页接口的测试;此外对于需要频繁更新调整数据的任务策划和关卡设计人员,他们会使用在个人电脑上架设的服务器,来避免数据更新对其他人测试带来的干扰。
前面说了些经验和建议,最后这里再说说Unity4.0后梦加的开发者还在翘首以待的功能。希望提供给其他开发者作为技术评估的参考,也希望Unity中国的大大们能够看到并帮助改进吧。
第一,Unity4开始全面进入了使用Retargetable(可重定向)动画技术和图形动画状态机的Mecanim的时代。Retargetable动画是游戏业的巨大福音,制作一套动画就可以适用于不同的骨骼和蒙皮模型,对于项目生产来说吸引力非常惊人。不过目前为止这个特性还不能用于页游的动态载入,因为负责动画Clip引用的Animator里不支持任何动态读取,可以说是阻碍页游项目全面升级Mecanim动画系统的最大障碍了。《蒸汽之城》在Unity3.X时代就开发了自定义的脚本FSM(有限状态机)来作为动画控制系统,尽管在Unity4里我们已经能够使用Mecanim的Avatar来运行本地原型里的动画重定向,但因为不能动态读取加载,一直还没有在游戏中正式更换动画系统,非常的遗憾。
第二,Unity4里说好的新GUI系统无限期跳票。GUI的开发对于任何项目来说都意味着很大的挑战和工作量,《蒸汽之城》的GUI使用的是Unity自带的GUI系统加上一套自己开发的设计工具来制作。在GUI的设计和图像生产方面已经做到了高效率,但是调整GUI功能时代码的修改量还是太大了。尽管很多人在官方新GUI系统跳票之后已经转投了第三方中间件的解决方案,但作为有自己工具开发组,对项目扩展性要求很高的网游团队,始终还是希望能够拿到官方的解决方案来定制,而不是依赖于某个随时可能停止维护的第三方插件。由于Unity4.0目前GUI系统的悬而未决,我们在配套GUI系统的优化方面也被迫遭遇了停滞。很希望这个系统能够最终尘埃落定!
第三,Timeline功能神龙见首不见尾,而且更糟糕的是Unity似乎已经不再维护以前的Animation View了。Unity4里增加了完整的新动画系统Mecanim,但对于一些简单的UI或特效动画,很多时候开发者还是希望能够在Unity里快速调整和制作。Animation View在Unity4里效率下降,子物体动画曲线的显示也有些奇怪。而集更多功能于一身的Timeline在Unite2012上亮相之后却迟迟不见更新的消息。Mecanim是一个专门处理骨骼动画、动作捕捉、动画分层和融合的专业系统,但除此之外一个有时间线和关键帧的编辑器还是对任何游戏项目都非常有用的,个人认为Unity团队不应忽略这方面的需求。
脚本来为测试加上配套工具,然后再交给资源生产部门来添加游戏中的资源。
地下城、任务和战斗系统因为涉及到很多和服务器端的通讯部分,如果需要测试就必须使用一个支持最简单的客户端服务端架构的单元测试档案配置。这里所说的档案,就是定义了你全部测试内容数据(或者去哪里找这些数据)的scriptableObject。包括你用来测试的帐号、角色信息、测试场景、任务或技能配置等等。以主城和地下城为游戏内容载体的《蒸汽之城》里,我们也制作大量测试用的地下城或主城场景作为任务和新功能生产的测试环境。测试环境由美术或策划来制作,然后交给程序部门来测试代码,最后再交给QA测试刚完成的功能。
Unity的强大原型制作能力主要还是应该体现在项目初期。一旦客户端服务端架构形成,可以在稳定的服务器环境上运行游戏以后,开发团队就应该把更多的精力集中在如何能够在实际服务器上快速添加新内容并进行测试。《蒸汽之城》有过三组测试服务器,分别用来进行代码、资源和网页接口的测试;此外对于需要频繁更新调整数据的任务策划和关卡设计人员,他们会使用在个人电脑上架设的服务器,来避免数据更新对其他人测试带来的干扰。
结语
制作网游或有联网功能的手游本身就是艰巨的工程,Unity让表面的一切看起来更美好和更容易,但不可否认广泛获得成功的Unity项目还是以相对简单的手机游戏为主。在网游制作方面开发者能参考的知识和信息还是太少了。梦加团队从零开始一点点的把Unity网游制作各个谜题拼起来,到了今天终于有了即将上线的高素质的页游《蒸汽之城》。希望我们这里总结的经验能够帮助国内业界的朋友们,我们的解决方案也有很多不足的地方,希望国内开发者们能够多多分享,促进Unity和网游开发技术的交流!《蒸汽之城》的中文本地化版本也在进展中,预计暑期就会跟大家见面!
>>相关产品