《The Last Of Us》的同伴AI(三):艾丽的战斗AI
首先第一点,与其让同伴角色单独去战斗或者逃跑,不如让同伴来帮助玩家战斗。在我们没做同伴AI之前,我们让艾丽能够跟乔尔一样使用各种武器去战斗,单独去击杀一些感染者,这很酷。但我们在测试时发现这种情况:房间里有10个感染者,乔尔(玩家)在房间这头干掉其中6个,艾丽在房间那头干掉剩下的4个。这不是我们想要的体验,这跟我们关卡设计的理念是相悖的,我们是希望他们携手共同去跟这10个敌人战斗。
第二点就是我们要避免艾丽总是在等待乔尔,也就是说我们希望艾丽在战斗中不是一个完全被动的角色,而是自己会执行一些行动内容的角色。
第三点是艾丽不能去影响关卡难度曲线。艾丽虽然能够在战斗中造成不小的影响,但玩家的关卡难度体验是位于同伴体验之上的游戏体验,难度体验曲线应该是位于更上层的东西,我们的关卡设计师早就已经平衡了关卡难度,我们不希望同伴AI的加入会影响这部分内容。
然后第四点是我们希望玩家大部分情况下都能注意到艾丽的行为。如果玩家不知道艾丽在干嘛,玩家就不太能感受到艾丽在战斗中的作用,我们之前想做的那些情感表达、两人的感情线之类的东西都会变得无用。注意我们上面说到的主题,我们希望艾丽在战斗中是有用的,所以我们就需要让玩家时刻知道艾丽的行动。
最后一点就是艾丽在没有枪的时候也能在战斗中发挥作用。玩过游戏的都知道,艾丽在游戏进程进行到某个点时,才能从乔尔那儿获得枪支的使用权。那么在这之前,我们也希望艾丽在战斗中能或多或少给乔尔提供一些帮助,而不是在旁边直瞪眼。
艾丽的投掷攻击(Throwing)
在2013年的某次玩家测试里边,有一次艾丽将一块砖头狠狠地砸在敌人上,然后大喊了一声:“You Asshole!”然后令我们震惊的是,旁边围观的其他玩家居然为此欢呼了起来。所以我们最后把艾丽能够投掷攻击的内容保留了下来。
投掷攻击其实挺好做的,而且在做同伴AI前,角色的动画、谈话内容、动作之类的早就做好了, 我们只需要让AI去判断艾丽在什么时候应该去进行投掷攻击。
然后就来说细节了,首先我们需要让艾丽去寻找并拾取投掷物,艾丽会在房间内随便搜索一下,几秒后会捡到一个一块砖头或者一个瓶子,艾丽得到之后就准备去攻击敌人。这些投掷物是艾丽特有的,乔尔并不能拾取它们,否则乔尔提前丢完了艾丽就只能干等着了。而且我们实际上设置了大量艾丽专用的投掷物,保证艾丽短时间内可以找到砖头或者瓶子。
然后就是决定什么时候去丢瓶子了,关键点就是在于我们希望艾丽在乔尔陷入危险时去帮助乔尔。这里我们会略微地给艾丽一个作弊能力(上篇文章说好的不作弊呢!),当敌人发现了乔尔时、当敌人即将要挥拳打到乔尔时、或者乔尔没有防御住敌人的攻击时,我们会把这些信息告诉艾丽的AI,然后艾丽就会知道乔尔处于危险。于是艾丽就会先移动到能看到乔尔的位置,再把投掷物丢到敌人身上。
这的确很酷!因为玩家在战斗中可能会没有弹药、可能会正忙着躲避、可能会刚刚被怪物击倒,这时一个来自艾丽投掷的砖头能够让形势瞬间扭转,然后乔尔可以用自己的拳头去反过来把敌人击倒。这个设定同样贯彻了我们最初的理念,大部分互动都是用来加深乔尔和艾丽之间的感情。
艾丽会被敌人抓住(Grappling)
我们在战斗中有这样一个设定,敌人可能会抓住乔尔,然后乔尔需要反击来挣脱。同样的,敌人也可能会抓住艾丽,艾丽需要乔尔的帮助来摆脱困境。
这乍一看是没有问题的,但通过游戏体验我们发现,玩家控制乔尔在专心攻击某个敌人时,忽然屏幕上跳出来一条信息说艾丽被抓住了,然后你必须要放弃眼前的战斗,跑过去营救艾丽,然后继续战斗。虽然这很合理,但这个设定在一定程度上其实影响了玩家的连续作战体验,也可能打破玩家的一些战斗思路和节奏。
于是,我们虽然保留艾丽会被敌人抓住的设定,但我们让艾丽不会每一次都求救,有时候艾丽会尝试自己去挣脱敌人的擒抱、然后反击敌人,实在是打不过的时候才会向乔尔求救。这样就能不失最初体验的情况下来保证玩家的战斗体验。
仅当艾丽跟乔尔之间距离不远、两人之间没有过多障碍、乔尔自身没有被抓住、且确保乔尔能够看到艾丽的时候,我们才会触发艾丽的求救。这时玩家控制乔尔去营救艾丽就相对自然一些,而且合情合理,玩家在营救完之后也能尽快回到战斗中去。
艾丽会营救被敌人抓住的乔尔(Melee Saves)
以及,我们在同伴AI中允许艾丽去营救被敌人抓住的乔尔。当乔尔被敌人抓住、正在奋力挣脱时,我们会让艾丽传送到乔尔旁边……对不起,我们为了营救的体验打破了上面我所说的一个原则,但我们这次只传送了几米远,所以不算!当艾丽传送过来之后就开始播放对应的动画,跑向乔尔、攻击抓住乔尔的敌人。
被营救的体验非常非常棒,你刚刚才救了艾丽、然后当你面对困境时艾丽就赶过来救你,两人之间情感会进一步加深。
艾丽的支援系统(Gifting)
接下来介绍的AI曾经令我惊讶不已,当Anthony(Max的同事)放进游戏时我甚至都还不知情,当我第一次在游戏中看到时我觉得相当惊艳。我们称之为艾丽的支援(Gifting)。
作为一个小女孩,当艾丽进入战斗后她很难去做一些战斗动作,比如开枪射击等等。但我们仍然希望她在战斗中有更多用处,希望艾丽身上能透露出她的一些习惯、一些性格特点,所以我们有了艾丽支援乔尔的这个点子。具体行为非常简单,就是艾丽会拾取场景内的一些武器、道具,然后递给乔尔,让乔尔去使用。
我们在调整AI时,设计师们早就把关卡难度做得很平衡,所以我们不可能凭空给予艾丽一些道具,而是让艾丽真的去场景中拾取道具再交给乔尔,艾丽需要去判断当前场景内有什么道具,是弹药还是医疗包。所以这不会影响到关卡的平衡,而是玩家偶尔从自己手动去收集变成有艾丽帮自己收集道具。
我们需要控制艾丽递东西给乔尔的频率。有一次测试时我忘记开定时器了,然后出现了这样的一个画面:
艾丽每隔十几二十秒就拿一个东西给我。
我刚进入场景时,艾丽说:“嘿乔尔,这个给你!”
我找了个掩体刚刚蹲下,艾丽说:“这里有点弹药,可能对你有用!”
我换了个掩体准备进攻,艾丽又拿了一个酒瓶跟我说:“你还需要这个吗?”
我把刚刚那些东西收拾了一下,抬头又看到艾丽:“嘿!拿着!这东西有用!”
我干脆转头看着艾丽,艾丽又不知道从哪个角落捡到一块板砖拿了过来……
高频率的支援不仅仅会降低关卡难度,而且会降低艾丽触发支援事件的价值,我们会渐渐对这件事感到无感,艾丽可能从一个很有用的角色变成了一个快递员。并且由于这个行为太过于频繁,导致我们并不会感激艾丽每一次的支援。因此我们最终把支援事件的触发间隔拉长到了几十分钟甚至几小时,让玩家对艾丽每一次的帮助都有足够深刻的感知。
艾丽在战斗中的位置(Positioning)
我们希望艾丽在战斗中能够保持靠近乔尔,然后希望艾丽去模仿乔尔的行为,比如当玩家控制乔尔藏在掩体后面时,艾丽也会藏在附近的掩体,具体就是跟我们上面说过的艾丽如何利用掩体。
如果乔尔站起来,艾丽也会相应站到乔尔旁边;如果乔尔掏出枪准备战斗,艾丽也会进入战斗姿态。但如果我们真的搞不懂玩家想要干嘛时,我们就会让艾丽继续保持潜行状态,继续待在掩体后面就好了。
我们认为在战斗中艾丽位置的最重要一点是:艾丽尽可能不要站在玩家跟前,也就是艾丽尽量不要出现在乔尔和敌人之间的位置。
玩家藏在掩体后方时,当前目标是思考通过怎样的战术去击败敌人,而如果艾丽这时跑到乔尔的视线中、甚至还占据了场景中某些位置时,这实际上是会干扰玩家的判断和策略。所以我们让艾丽尽量位于乔尔的身后或者身旁,而非身前。
艾丽永远不会打破潜行状态(Stealth)
接下来我们要确保的一件事情是,艾丽永远不会打破己方的潜行状态。也就是当玩家控制乔尔开始潜行并接近敌人时,敌人永远只会是因为玩家被发现、玩家主动现身、玩家主动开枪射击而发现玩家,而永远不会当玩家还在潜行时就能发现艾丽。我们可以想想一下,当乔尔躲在箱子后好好的,艾丽却不小心把两人的位置暴露给敌人、或者无缘无故就开始拔枪射击敌人,这种体验非常不好,玩家对整个关卡的控制能力极大下降。
这里插一句,有时候一些游戏会特意用控制力这一点来强调游戏剧情,比如《战神》里有一段是这样:奎爷的儿子阿特柔斯跟奎爷闹别扭然后生气了,于是接下来几场战斗里玩家都不能控制阿特柔斯的战斗行为,直到两人和好之后才恢复正常。
因此,为了避免上述的情况出现,我们做的一件事就是极大地降低艾丽的射击和攻击欲望。这本身是说得通的,艾丽还是孩子,而且是个女孩,而且区别于那些感染者、艾丽是个有理智的人类,所以她不会像它们那样充满攻击性。艾丽永远不会主动射击敌人,除非乔尔被击中了、或者乔尔和艾丽已经被敌人发现并遭遇到围攻等等。
要注意的是,我们上面说的潜行不单单是玩家在战斗发生前的潜行,还包括玩家在战斗中借助掩体来逃脱的潜行(snuck away),我们用一个例子来说:
上图中左边是一个敌人,他面对的方向是他最后一次发现乔尔的位置,我们看到乔尔跟艾丽已经从那个位置逃脱并藏到掩体后,而且借助掩体已经移动到另一侧了,我们就会把这个过程称之为战斗中的潜行(snuck away)。这时候,如果艾丽还沿用我们战斗中协助乔尔的逻辑,艾丽就会主动站起来举枪射击敌人,进而暴露了乔尔的位置,使刚刚玩家所做的一切(潜行)白费了。所以在这种情况下,我们通过AI让艾丽去保持安静、不说话,当然也就不会开枪,相当于进入了我们上面说的潜行模式(stealth)。玩家此时就可以完全根据自己的想法和战斗思路去继续通关关卡。
艾丽如何去射击敌人
接下来我们要讨论的是艾丽的射击逻辑。《最后生还者》里对艾丽的定位是允许她在游戏中后期持枪射击敌人,然后并不希望她成为一台杀戮机器,也就是说你不可能看到她连续把20个敌人干趴在地上。
然后艾丽射击造成的伤害应该是相对真实的,比如一个乔尔要花3颗子弹就能杀死的敌人,艾丽总不能因为她是小孩子就要花20颗子弹才能射死对方。所以我们在思考这部分逻辑时,会从艾丽的射击伤害、射击精度、开枪频率这几个方面来进行考虑,目的就是希望艾丽能在战斗中帮助乔尔,并且能够在自身有危险的时候能通过开枪来规避危险,而同时又不会让玩家觉得艾丽的杀伤力太强。
插一句,《战神》里一直有一个梗:战神与战神的老父亲,说的就是奎爷儿子阿特柔斯的攻击力和技能实在是很高,而且控制效果不俗,于是玩家圈里有不少人就会拿战神的昵称来打趣。但在《战神》里阿特柔斯毕竟也是个神,而且作为战神之子,他在游戏中的战力要明显比《最后生还者》里艾丽要强得多,更何况他的真实身份是洛基,所以这一切其实也就说得通了。
首先,艾丽的射击伤害是要跟乔尔一致的,最多只能有一丁点的差别。因为无论是大人开枪还是小孩开枪,打出去的子弹都是一样的,不同点最多就是乔尔能爆头。
然后,我们会调低艾丽的射击精度,降低艾丽的命中率。但这会看起来很傻,敌人就站在前面不远处,但连续几枪的射空还是会让玩家感觉体验不好。于是我们给艾丽加入了一些紧张、发抖的待机动作和攻击动作,看起来艾丽就是那种不擅于开枪、也不愿意主动杀人的小女孩,并且通过这种方式也让命中率偏低的射击看起来很合理。
所以,在低命中率的帮助下,我们也不用太过于压缩艾丽的开枪频率,反正也不会造成太多的伤害。反而如果开枪频率太低的话并不好,就比如一个敌人已经冲到艾丽面前几米了,这时候还不开枪打他的话就会很奇怪。
还有一件事情就是当艾丽在屏幕外、也就是玩家视线之外时,她基本上不会对敌人造成伤害。有人会说,这不是很奇怪吗,玩家知道艾丽跟一个敌人在一个房间内缠斗,结果艾丽不会对敌人造成伤害。而通过我们的观察,玩家在战斗中一般都会沉浸在乔尔跟敌人的战斗中,玩家才不会一直留意视线外的艾丽。然后我们会有个定时器,每隔一段时间艾丽就会瞄准玩家视线内的敌人并且攻击他们,尽量让两个人的目标一致。
并且当艾丽在屏幕外时,我们会让艾丽发出一些诸如“Take that mother f******”的声音来引起玩家的注意,而实际上她并不会对敌人造成什么伤害,这在关卡里实际上保证了关卡的难度是不会因此而发生变化,玩家也很难利用这一点来使关卡变得更高或者更低。然后再通过上面我说的那个计时器,让艾丽回到乔尔身边战斗,从而使艾丽在战斗中不至于变得无用。
敌人尽量选择射击乔尔,而非艾丽
这里我们还会讲到敌人的瞄准逻辑,这部分只是一个小点,这里可以简单带过。就是我们会把所有敌人的射击目标都设置成了乔尔,只有少数特殊的敌人会主动攻击艾丽。这其实很难被玩家察觉,因为根据我们前面讲到的跟随逻辑,艾丽一般情况下不会距离乔尔太远,所以敌人的子弹就感觉是朝俩人射过来一样。
艾丽在切换掩体时,默认不让敌人发现
啊……这里我们不得不去作弊了。
我们的敌人总是能够看到视野中的乔尔和艾丽,不可能对一个出现在自己面前的角色不闻不问,而当艾丽不得不在一些看起来比较蠢的掩体中切换时,有可能就会被发现,然后导致己方的潜行状态被打破,然后敌人就会立刻拔枪射击,乔尔不得不为艾丽的失误买单,被迫提前进入战斗。
这里我们陷入了一个两难境地,要么我们打破之前所说的“永不作弊”原则,让艾丽在掩体切换时默认不让敌人发现,要么就向上面所说的那样,艾丽有可能让敌人发现然后玩家被迫进入战斗。
后者这个选择虽然看起来很真实,但我们在游戏中毕竟还是要以玩家体验为优先,玩家控制着乔尔好端端地躲着,不能因为同伴的失误而葬送了玩家的操作。所以我们在不得已之下,选择了这种作弊方案,这虽然有点滑稽,但毕竟在实际战斗中出现的频率不算太高,所以我们还是接受了。
《神秘海域4》里这种现象其实蛮多的,但这是因为神海4的需要攀爬的时机实在是太多了,同伴山姆经常在敌人脚下爬来爬去都没人管。
还有一些我们想做但还没做的战斗AI
正如演讲一开始时所说,我们只有四五个月的时间来做这个同伴AI,所以我们其实有一大堆想做但是还未做的逻辑。比如说视野范围地图(exposure map),我们想捕捉到NPC们的视野范围,这样就可以让艾丽在切换掩体、移动时不会进入到对应的位置离里去。又比如说一种智能的瞬间传送,虽然之前我们说了我们不会在游戏中对艾丽进行瞬间转移,但在一些很开阔、空间很大的场景里,如果艾丽实在是距离乔尔太远,玩家有可能听不到艾丽的求救信号之类,所以我们还是希望做一些短距离的传送,只要这些传送不被玩家发现、不会惊吓到玩家就可以了。
好了,以上就是同伴AI里战斗部分的主要内容。直到现在,艾丽在同伴AI的帮助下已经是一个很生动、很平衡又很有趣的角色。接下来最后一部分我再介绍一些相对独立的AI逻辑,这些AI能够进一步让艾丽这个角色看起来更具有生命力。