你好,我是YC!最近工作忙得焦头烂额,两周时间转瞬即逝,眼看自己刚立的Flag就摇摇欲坠,故决定先“水”一篇文章续命。恰逢下周组会上轮到自己分享,一直苦于没有找到合适的主题,所以正好借此机会,一箭双雕。
关于“换皮”
本篇文章被打上了“换皮”的标签,并不是说本文与“游戏换皮”相关,而是指本文的主要内容是对他人所做分享的梳理、总结和转述。当然其中也会补充一些我自己的思考和结论,必要时也会对结构进行调整,防止“换皮”沦为“转载”。
之所以要“换皮”,一是因为以我目前的水平,确实很难在两周时间内输出一篇质量让自己满意的技术文章,“换皮”这种形式可以很好地解决这个问题;二是因为目前游戏开发领域,国外许多高质量的分享,都没有被很好地转化成便于国人阅读和理解的内容,大部分都是自己想法的备忘,缺少相关知识和上下文的同学很难读懂,因此“换皮”也是我个人希望为游戏开发所尽的一份力量。
书归正传,本篇文章“换皮”的对象是GDC 2019上,来自圣莫妮卡工作室(Santa Monica Studio)《战神4》项目组的战斗主策(Lead Combat Designer)Mihir Sheth(姑且译为“米赫·赛斯”)发表的分享,题目为“Evolving Combat in ‘God of War’ for a New Perspective”(《战神4》战斗系统为新视角所做的进化)。分享围绕战神4中的战斗系统如何适配新的相机设定这一主题,介绍了敌人如何站位、主角如何瞄准和攻击等技术和设计的细节,以下为本文目录:
背景介绍(Background)
截图来自Youtube视频:History/Evolution of God Of War (2005-2018)
先来看一组图片,图片内容是战神1-4的游戏战斗截图,直观上最大的一处不同是,战神4的相机更近了。实际上,与前作相比,战神4的相机视角从远距离的固定视角(Pulled back fixed camera),改为了近距离的越肩视角(Over the shoulder camera),这也意味着当你在战神4中向后推动左摇杆时,你看到的不再是主角的正脸,而是主角的后退动画(如果不理解就想象一下“原神”和“吃鸡”的后退操作)。这样无疑能给玩家更强的代入感,因为你看到的画面与主角看到的画面基本上是一致的,但无疑也与战神系列固有的一些游戏设定产生了不少矛盾,其中最重要的一点就是,越肩视角无法让战神玩家在一对多的战斗中保持自信和攻击性。
我们再看一组图片:
可以看到,在玩家可以同时对抗多个敌人的游戏中,战斗相机一般会拉得比较远,以增大玩家的视野,让玩家感知周遭更多的进攻机会和威胁。而相机越近,玩家往往就越需要专注于眼前的敌人,来自屏幕外的威胁也就越少,因为如果玩家总是被屏幕外的敌人豪无征兆地攻击,游戏体验也势必会大打折扣。
显然,历代战神需要继承奎爷充满攻击性的特点以及可以一对多的基因,因此战神4中相机设定的变化,引发了一系列玩法上的矛盾。为了解决这些矛盾,战斗系统上就必须做出一系列改进,引用讲者的一句话就是:
The difficulty needed to come from the game itself, not the controls and camera.
简而言之,开发者希望即使改变了相机设定,玩家还是能够拥有与前作类似的战斗体验,充满自信地操控奎爷,砍瓜切菜般击溃众多敌人。那么接下来本文就按照追踪敌人、瞄准敌人、攻击敌人的逻辑,具体介绍下战神4的战斗系统到底为了适应新视角做了哪些进化。
追踪敌人(Tracking Enemies)
讲者将这里的“追踪”定义为,感知当前战斗中存在的威胁。因此我们要解决的第一件事就是,如何定义“威胁”。
敌人的攻击性(Enemy Aggressiveness)
还是先来看一张图,出自电影《叶问》,在叶问说出著名的“我要打十个”后,电影里有一段爽快的一对多打戏,但慢下来你会发现,这场战斗中虽然叶问需要同时面对多个敌人,但每个时刻只会有一两个敌人与叶问正面交锋,其余敌人则是围绕他分散站位,充当背景。这样设计不仅能够突出画面的重点,同时也能保留一对多的压迫感,再辅以特写和远景之间的切换,观众基本无法察觉。
游戏中也一样,如果让玩家同时面对来自四面八方不加约束的攻击,玩家很快就会无从招架,游戏画面也会变得混乱不堪。因此游戏一般会通过给敌人增加攻击标记的方式来约束敌人,拥有标记的敌人被允许攻击玩家,而没有标记的敌人则在玩家外围徘徊,等待获取到标记后再上前进攻。
战神4也不例外,敌人攻击标记的管理主要包括两个步骤:计算攻击分数和分发攻击标记。
计算攻击分数(Evaluate Aggression Score)
战斗时,游戏每隔一小段时间都会为每个敌人计算一个攻击分数,得分越高越有机会拿到攻击标记。攻击分数包含以下四个维度的信息:
- 敌人本身能够转换到攻击状态:敌人没有处于受击硬直或者其他异常状态,能够正常进攻
- 进攻优先级:该项主要依赖策划配置,并且是一个与距离有关的值,即根据敌人自身与玩家之间的距离会有不同的取值,直觉上距离越远进攻优先级也越低,但不同种类的敌人会有各自的数值,例如一个距离玩家较远的Boss,也可能比距离稍近的小怪优先级高
- 敌人是否是玩家当前瞄准的目标:瞄准敌人的细节在下文的“瞄准敌人”部分会介绍,这里可以先简单理解为一个布尔值
- 敌人的行动排名:这是一系列与敌人种类无关的参数,仅仅去考察敌人是否位于屏幕内、与摄像机的夹角以及与主角的距离等因素
值得一提的是,以上各维度信息是按照重要程度排序的,也就是说如果某个敌人高位评分为0,则其低位分数再高也不会比其他高位评分非零的敌人最终的得分高。
分发攻击标记(Hand Aggression Tokens)
游戏中的主角有自己的攻击标记池,其中存放着特定数量的攻击标记。战斗中,当游戏计算出每个敌人的攻击分数后,就会将它们按照分数进行排序,并依次让它们从主角的攻击标记池中获取指定数量的标记(这个数量也取决于策划配置),如果敌人取得了足够的攻击标记,则会变为攻击状态,而如果主角标记池中的标记已经用尽,则剩余没有取到足够攻击标记的敌人就会变为非攻击状态。
以下图为例,主角的标记池中共有14个标记,全部4个敌人按照攻击分数排序后,洋红色、黄色和绿色的敌人依次瓜分了主角的全部标记(具体获取标记的数量配置在下方表格的Prox列),并转变为了攻击状态(表格A列带星号标记),而剩余的蓝色敌人则只能为非攻击状态,从而在距离主角较远的位置附近游走。
同样值得一提的是,攻击标记池的设计,给改变游戏难度提供了一种途径,即通过增加或减少每个敌人能够获取的标记数量,就能够控制敌人的群体攻击性。
敌人的站位(Enemy Positioning)
在能够区分哪些敌人有“威胁”后,接下来就要解决敌人的站位问题。战神的前作中,战斗系统可以简单地将不同攻击性的敌人,分散在以主角为圆心的圆上,攻击性越强,半径越小。因为即使敌人将主角包围起来同时进攻,被拉远的相机也能让玩家及时感知每个敌人的站位,从而做出反应。
但在战神4中,由于相机的调整,我们不再能够看到主角后方的区域,如果仍然采取之前的策略,玩家就很容易会为了将身后的敌人置于视野内而后退,这显然与游戏设定相悖,因此开发者需要改进敌人的站位策略。
基于权重地图的站位系统(Weighted-map-based positioning system)
一个对前作站位系统的自然改进就是,对同心圆上的不同位置加上权重,通过降低主角后方区域的权重,来让敌人更倾向于站在主角前方。
如上图所示,基于权重的站位系统同样会周期性地考察主角周围的同心圆区域,并对每个区域赋予一个权重,权重越高,说明该区域越适合敌人站位。可以看到主角正前方视野内有许多权重较高的红色点,而后方区域只有在比较远的位置才有两个红色点。每个敌人的目标也很明确,就是不断地检查并移动到自己附近权重最大的区域。
值得一提的是,计算区域权重前,游戏会先排除那些不在NavMesh上以及与主角位置之间没有直接可达路径的点,防止敌人被导航到一些奇怪的位置上。
虽然这样的改进十分直观,但也存在一个严重的问题,那就是权重地图的时效性。游戏并不会每帧都去更新权重地图,但玩家和敌人却是每时每刻都在移动的,随着玩家镜头一转,上一次计算的权重地图就会大规模失效,导致在下次计算前,敌人的站位都无法被很好地管理。
基于区域约束的定位系统(Zone-constraint-based positioning system)
We changed the goal from “picking optimal positions for each enemy” to be something much simpler: “prevent enemies from getting into bad positions”.
上述站位系统存在的缺陷,使开发团队不得不思考新的方案。最终他们将思路从“为每个敌人选择最佳的站位点”转变为了“防止敌人进入不好的站位点”,本质上就是从“我要科科90+”到“只要不挂科就行”。既然为每个敌人选择最佳的站位点太复杂,那么就退而求次,只要确保敌人不要站在那些不好的点位即可。因此当下的问题就变成了,如何定义”不好“。这里开发团队采用了所谓“区域约束”的概念,它最开始包含了两个方面的约束,一方面是敌人自身的位置约束(Positional Constraint, “Where do I want to stand”),二是敌人之间的间隔约束(Separation Constraint, “How much space do I take”)。只要敌人目前的站位符合这两方面的约束,那么就说敌人站在了一个”好“的位置上,就不需要移动,反之就需要去寻找新的位置。
- 位置约束(Positional Constraint)
位置约束中,对于有攻击标记的敌人,它们的位置约束是玩家相机前方的一片新月状的区域(上图中的红色区域),即它们必须站在这片区域内。而对于没有攻击标记的敌人,它们在位置约束上与前作一致,即站在以主角为圆心的一个同心圆附近即可,因为它们并不会攻击,即使把玩家包围起来也可以接受。
- 间隔约束(Separation Constraint)
间隔约束中,对于有攻击标记的敌人,它们会在自身周围形成一个圆形区域,其他敌人将不被允许再站在该区域。而对于没有攻击标记的敌人,它们的间隔约束也是月牙状,只不过更接近矩形。
施加了这两个约束后,上图敌人的站位在游戏中的效果就如下图所示:
可以看到,这种站位效果不但能防止有攻击性的敌人跑到屏幕外,还能让敌人更加分散,最大化越肩相机的视觉效果。另外,与之前的权重地图相比,基于区域约束的站位系统的时效性也更好,计算也更简单。而且之前使用权重地图时,很可能由于没有考虑敌人之间的间隔距离,从而出现敌人扎堆站在某个高权重点位附近的情况。不难猜测,区域约束的规则和形状,肯定也是开发团队不断迭代和调试后的产物,另外不同的敌人也可以配置不同的形状,使得站位结果更加多样化。
然而,目前的约束还存在一个问题,想象一下当玩家将屏幕内的敌人全部击杀后,玩家身后的某个敌人会获得攻击标记,此时由于位置约束,它会试图走到玩家前方,并可能在身后攻击玩家。这种偷袭行为无疑又降低了玩家的”攻击自信“。因此开发团队后来专门为屏幕外的敌人增加了一种约束来防止上述情形的发生,这种约束被称为“象限约束”。
- 象限约束(Quadrants Constraint)
Enemies that you weren’t actively keeping track of would stay relatively in the same area as you’d last seen.
象限约束的核心就是:让敌人待在你最后看到他们的方位。简单来说,当你不去看某个敌人时,它的站位会被限制在某个坐标系下的某个象限内。这个坐标系以玩家为原点,世界空间的方向为坐标轴。以下图为例,主角当前的象限约束是两个红色同心圆组合成的圆环,而蓝色敌人对应的约束区域就是蓝色虚线组成的新月状区域,它只能在这个区域内站位。
下面是一段解释三种约束规则的视频,原始演讲中搭配了讲解,这里不再赘述,不过有几处理解上容易出现偏差的点,我认为需要解释一下:
- 位置约束和象限约束都隶属于主角,间隔约束隶属于敌人。也就是说每个时刻中,位置约束和象限约束都只有一个,而每个敌人则有自己的间隔约束,视频中,系统在不断地变换展示隶属主角的两种区域约束,并没有展示敌人之间的间隔约束
- 视频中可以注意到,主角有两个不同的象限约束区域,一近一远,我推测是,如果玩家从敌人近处经过,并把它甩在身后,游戏就会使用主角近处的象限约束,这样在敌人拿到攻击标记后就可以从身后攻击主角。如果主角只是将远处的敌人甩在身后,那么敌人就会受主角远处的象限约束区域的限制,此时即使它拿到了攻击标记也无法近身攻击。
- 在区域约束的方法中,游戏没有再在主角周围动态生成网格点,而是事先在地图的Navmesh上预计算好了网格点。
- 所有区域更新都有一些卡顿,猜测是由于这部分的计算并不是每帧都进行而引起的。
- 象限约束中的“象限”的原点虽然是主角,但方向是定义在世界空间中的,也就是说这个象限不会随着主角朝向变化而变化,这样才能保证敌人总是待在某个大致的范围内。
以上就是“追踪敌人”的全部内容,令人略感遗憾的是,原演讲中,在这之后的“瞄准敌人”和“攻击敌人”部分都比较偏重介绍设计,没有讨论太多技术细节。不过了解它们还是有一定益处的,说不定就会对自己当前的工作内容产生启发,我们下节继续!