分享

Unity中M.E.R.C.的程序化关卡生成(一)

 勤奋不止 2017-06-03
版权所有,禁止匿名转载;禁止商业使用;禁止个人使用。

翻译:赵菁菁(轩语轩缘)  审校:李笑达(DDBC4747)

程序关卡生成是一种为游戏创建更丰富内容和出人意料场景的好方法。我们本想通过大量手工制作的方式为M.E.R.C创建故事线,但是,作为一个小的独立团队,我们知道我们没有足够的时间和资源来为这样一个大型游戏创建足够的内容。我们还想为游戏增加随机性和大量的可玩性。程序化关卡生成使得我们可以创建一个广阔的充满变化的世界,如果我们的小团队试图靠自己用双手完成这一切,那将是不可能的。使用程序生成使我们可以为游戏添加更多的内容,创建更好的用户体验。M.E.R.C.已经发布在Steam的EarlyAccess上,来下载吧

M.E.R.C.是什么?M.E.R.C.是一个实时的小队战术游戏。场景位于Neotopia的反乌托邦未来,你同时控制一个四雇佣军的小队,从俯瞰角度发布命令、激活的特殊能力。小队中的每个佣兵都有战斗、工程和劈砍的特殊技能,你需要在任务中使用这些技能。M.E.R.C的画面类似刀锋战士的怀旧风格,有雨中黑暗的贫民窟和城市屋顶,还有城市中蜿蜒的街道和霓虹灯。这个故事让玩家卷入强大的集团之间,这些集团互相斗争为的是争取Neotopia的控制权。作为雇佣兵,你被雇用来完成这些集团的各种任务,如绑架竞争者科学家或暗杀叛逃员工。你所接受的每一项任务都会影响你在不同的集团的地位,从而改变游戏世界。考虑到这一切,让我们来看看我们的程序化关卡生成的要求。

Unity中M.E.R.C.的程序化关卡生成(一)

关卡要求

我们的关卡是在一个城市贫民窟和屋顶的迷宫中,为了增加游戏的可玩性和趣味性,需要给这些关卡提供一些特殊的结构设计。我们决定将多个较小关卡的块组合起来,为我们的任务创建更大的关卡。通过这样做,我们可以手工制作有趣的、可重用的小块结构和在某些程序随机中的层,让每一关卡都有手工制作的感觉。为此,我们确定我们的程序关卡必须:

 - 包含一条主路径
 - 包含1-3条为目标和战利品设计的死路
 - 包含1-3条捷径作为备选路线
 - 在每个关卡小块中生成随机道具和载体
 - 基于“游戏节奏图(tempo chart)”量产NPC
 - 基于任务难度生成不同类型和等级的敌人
 - 配合使用Unity的导航网格(NavMesh)系统
 - 通过网络为COOP生成完全一致的关卡

以上是针对我们游戏运行、世界及人物长度的特定要求。每个游戏对于一个程序关卡系统都有自己的要求。我们希望能在十分钟内完成任务,但如果玩家探索的更为彻底,花费的时间可能要加倍。这意味着路径长度的多样性是一个重要的考虑因素。

对于我们来说,最大的挑战是如何把我们所有的要求组织在一起,最终获得一致而有趣的关。那么我们是怎么做到的呢?如果你从一个完整的关卡入手思考,包括布局、机密、节奏和任务目标,是很难想出如何程序化地创建这些内容的。我发现如果分层思考的话则会容易的多。可以把程序关卡看作是建立在多个通路之上,而每个通路则是向关卡中增加一个新的复杂层。从逻辑上来说,你可以从最基本的层开始启动设计。在我们的游戏里,我们是从关卡的布局或者说路径开始启动的。


生成关卡路径

我们的程序关卡系统要解决的第一个问题是如何生成一个有趣的主要路径,这条路径包括死胡同和捷径。我们在Unite 2014中的一个演讲中找到了答案,这个演讲是由来自17-BIT的Zach Aikman给出的游戏Galak-Z(宇宙战士)关卡生成的介绍。(17-BIT是个游戏公司,Zach Aikman是其中一员,Galak-Z是他们开发的一款游戏)你可以在这里观看完整的演讲)。

Zach的演讲非常有意思,建议大家看一下,简单总结如下:我们使用改造后的希尔伯特曲线(Hilbert Curve)算法生成我们主要的二维路径。这个算法提供了一个有趣的而独特的蜿蜒路径,这是我们游戏的完美起点。Galak-Z的开发者们用此算法为其游戏创建了一个2D侧面视角的路径,而我们则是创建了一个2D的俯视视角的路径。想象下面的图片是我们游戏中一个俯瞰的街道。

Unity中M.E.R.C.的程序化关卡生成(一)

(图片由上面提到的Galak-Z演讲提供)

在生成主路径之后,我们将对所有有效的捷径地图单元格进行评估,并随机选择使用一些捷径。一条捷径不会让你穿越整个地图,但它会让你在绕过一段主线路径,并可能避开一些敌人。我们编码进行了限制,以确保捷径不会太长或出现太频繁。当把这些捷径加入我们的关卡块中时,我们常常选择把捷径放在可破解的门后,或者要求玩家进行一些其他操作来找到捷径。这为关卡的主路径增加了多样性,也提供了另一种方法来测试玩家的技能。

Unity中M.E.R.C.的程序化关卡生成(一)

接下来,我们随机添加带有死胡同的支路,其中没有地图单元格存在。这些支路作为备用路径可以打破主线游戏流程,并且提供理想的地点去放置战利品、隐藏的秘密和特殊的任务目标,如找到非玩家角色(NPC)并刺杀。根据任务目标,我们为每个关卡随机生成一到三个死胡同。每个特殊的任务目标被放置在一个死胡同的尽头。

Unity中M.E.R.C.的程序化关卡生成(一)

这个想法是,你通过开始地图单元的一艘运输船到达关卡,这个单元那就是主路径开始的位置。然后,你引导你的雇佣军通过关卡,在到达主要路径的末尾之前完成你的目标,在末尾处你们被疏散,任务结束。在每个关卡中,任务的完成目标是必需的。任务目标让主要路径逐渐消失,这会强迫你继续探索这个关卡。其他死路是可选的,提供秘密和额外的战利品。这提供了一个良好的融合,这样一来,如果玩家只是想完成任务,他们可以快速通关,或者如果玩家愿意的话,可以花更多的时间来探索。

一旦我们生成了具有捷径和死胡同的完整路径,我们将它转换成一个关卡块列表来加载。每个关卡块都是Unity中的一个场景,所以我们为每个场景都以特定模式命名来显示其配置。从生成的路径中,我们将每个地图单元格转换为如下模式的场景名称。此模式包含块的主题、连接和变异。所以在<主题>_<主要路径连接>_<捷径连接>_<死胡同连接>_<变异>这种模式中,一个关卡块可能有这样的场景命名:“slums_03_-1_-1_A”。

主题是关卡块的视觉样式。主题中所有关卡块必须能够与同一主题中的任何其他关卡块无缝连接。例如,以“贫民窟”为主题的所有关卡块必须能够在逻辑上和图形上相互连接。我们还开发了一个叫“屋顶”的主题,与连通的街道类型不同,这个主题是建筑物顶部由坡道和通道连接。通常一个主题中的所有关卡块大小都是相同的。我们块的大小通常是40x40单位。

基于希尔伯特曲线和我们生成路径的结构,每个关卡块将有两个主路径连接,零或一个捷径连接,和零或一个死胡同连接。关卡块不能同时含有捷径和死胡同连接,因为这种情况不会被用到。每个连接对应于关卡块的边缘,每个边缘被标记为零到三之间的数字,如下图所示(如果要标记不存在的连接,如没有捷径时,我们使用“- 1”)。

Unity中M.E.R.C.的程序化关卡生成(一)

例如,标有“03”的主路径连接的关卡块在底部(0)和右侧(3)有连接打开。主路径连接标签总是从最小到最大排序(例如:“03”,而不是“30”)。重要的是要注意:当并排放置关卡块时,连接不一定要100%均匀排列。向一些连接中加入“参差不齐的设计”增加了多样性,同时使得关卡块连接处看起来没那么顺畅。然而,连接必须始终以确保路径连通的某种方式排列。

变异给关卡设计师提供了一种方法,让相同的关卡块有不同的版本。例如,看下面两个标记为“A”和“B”的“01”的主路径连接变异,没有捷径。当生成关卡时,我们的系统为每个关卡块随机选择一个可用的变异,创造更多的视觉多样性。

Unity中M.E.R.C.的程序化关卡生成(一)

当我们加载每个关卡块时,基于关卡块属于路径的哪个位置,我们把它移动到世界中的正确偏移位置上。这意味着块中不能有标记为Unity静态合并的网格(因为当你尝试移动它们时,内容将被破坏)。然而,Unity的动态合并仍然适用于此系统。下面是随机生成的关卡布局的一些示例图像(红色区域是建筑物的捷径,蓝色区域是建筑物的变化)。这些都是布局概念论证,没有完成美工设计。

Unity中M.E.R.C.的程序化关卡生成(一)

我很高兴能更详细地讨论这些问题,希望大家可以提出的任何建议和反馈。你可以在推特上联系我@velvetycouch

在《Unity中M.E.R.C.的程序化关卡生成》的第二部分中,我们会继续讨论我们克服的照明和NavMesh问题,以及怎样基于游戏节奏生成NPC。第二部分在这里!


【版权声明】

原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多