橡皮鸭游戏是如何开发《邪恶巫师》中 Boss 战的

橡皮鸭游戏 (Rubber Duck Games) 是备受尊敬的 GDC 2023 最佳游戏奖获得者之一,它揭秘了他们如何创造一场引人入胜的 Boss 大战。这篇客座博客将介绍团队成员 Banki 和 Sergio Wajswol 的整个旅程,从设计和原型制作到动画、测试、平衡,以及最终确定视觉效果和音频。 邪恶的巫师。
嘿,读者们!我是 Banki,Rubber Duck Games的游戏设计师和制作人。我们充满幽默的动作角色扮演游戏 《邪恶巫师》 现已在 Steam 和 Xbox 上推出,我想让您了解一下我们如何开发 Boss 战的幕后花絮。
《邪恶巫师》 是一款类银河战士恶魔城风格的游戏,玩家将扮演一个被击败的“最终魔王”,向被诅咒的英雄发起复仇之战。
这场复仇之旅将带领玩家穿越迷人的像素艺术环境,其中挤满了成群的敌人,玩家必须战胜这些敌人才能夺回属于自己的一切。虽然主角曾经是一位强大的巫师,但在与英雄的一场战斗中失败后,他失去了法力,他们必须重新夺回法力,潜入城堡,发动毁灭性的复仇。
游戏中第一个被击败的英雄是强大的冰魔法师海尔加。我们将以她作为这次深入探讨的示例老板。
让我们从头开始。为 邪恶巫师 设计一个老板(和每个敌人)有点棘手。尽管玩家正在与好人作战,但我们知道他们仍然应该看起来足够危险,才能被识别为敌人。
对于老板,我们在著名游戏英雄中寻找灵感和参考。在创作《海尔加》时,我们从 《魔兽世界》中的 吉安娜 那里获得了很多灵感,因为两者有很多相似之处。
第一步是准备一个电子表格(我们对游戏中每个老板都使用这个表格),其中详细记录角色的主要特征,机制和一些参考资料。

设计好机制后,我们就可以进入下一步:原型设计。
现在是时候向团队展示新老板的设计了,因此我们召开会议,我浏览一下文件并解释我的一些决定。
在这里,我们对设计进行了一些调整——在某些情况下,某种机制可能太难开发,或者动画太复杂而无法绘制,等等。我们试图按时完成任务,因此有一些事情我们应该考虑,以便在我们有限的时间内成为最好的老板。
当谈到原型设计时,我们的首席程序员 Diego Ordóñez 是这样说的:“Hailga 是 《邪恶巫师》 中的第一个 Boss,也是我一生中第一次为 Boss 编写程序。我知道这是一项艰巨的任务,因此我开始做每个程序员都会做的事情:将攻击分成简单的任务并分别执行。这个 Boss 的攻击很简单,只需重复使用投射物即可。”
“冰弹和冰导弹的攻击对玩家来说感觉非常不同 - 一个很容易躲避,而另一个则代表了战斗中的挑战,”他继续说道。“关键的区别在于攻击组件如何产生冰弹以及面向玩家的弹丸数量。通过简单的调整,我们能够重复使用整个系统来呈现两种不同的攻击。所有这些都很有效,直到我必须开始发动暴风雪攻击。”
对于海尔加的战斗,我们想为这场战斗带来一些新的东西,并认为风可能会很有趣。这与我们在 《邪恶巫师》中所做的任何其他事情都非常不同,所以我必须从头开始。其基本思想是从随机方向产生风,以便将玩家移向布满可能造成伤害的尖刺的墙壁。抵御这种攻击的最佳方法是寻找掩护,因此我们在战场上产生了一些钟乳石来用作挡风石。如果玩家位于冰钟乳石后面,风将不再对他们施加力量。
我们首先创建一个攻击组件来负责管理我们使用的不同系统。该系统使用了钟乳石、风发射器和暴风雪视觉特效。我将重点介绍前两个,而视觉特效将由 Sergio Wajswol 在这篇博文的后面部分介绍。
钟乳石是使用圆形对撞机生成的,以在其中获取随机点,然后使用这些位置创建在 Y 轴上具有偏移的钟乳石。应用协同程序,我们通过降低 Y 轴来使物体下落——很简单。一旦钟乳石生成,我们就开始控制风。该组件的作用是作为一个矩形形状的大风扇,围绕圆圈的边缘旋转。

由于我们需要从随机方向吹风,我们必须将发射器指向中心,这样该区域内的所有东西都会受到影响。风控制器有一个风发射器,可以存储风的旋转、方向和位置。当我们旋转组件时,发射器会计算这些值并将它们应用于风(这只是一个方向和一种力)。基本上,一个 Vector3 和一个浮点数。
如上所述,也可以使用挡风器来阻挡风。该组件有一个 BoxCollider2D,用于检查与玩家的碰撞。如果玩家靠近风阻器,OnTriggerEnter2D 将启用风阻器,而当玩家离开对撞机时,OnTriggerExit2D 将禁用它。下图中玩家和发射器之间的青色线说明了这一点。当线为绿时,玩家受到保护。

最后,我们需要让玩家受到风力并沿着风向移动。为此,我们有一个 WindReceiver 组件。它负责检查风对玩家的影响有多强以及从哪个方向影响。该信息是通过从玩家向风接收器进行 射线 投射来收集的。然后利用这些信息来了解风发射器是否对接收器产生影响、影响的力度有多大、影响的方向是什么。一旦我们掌握了所有的信息,我们就使用我们自己的移动控制器施加风力并将玩家移动到我们需要的方向。
当 Diego 开始发起第一次攻击时,我开始给 Hailga 一些行为。
对于 邪恶巫师的人工智能,我们使用了一个非常有用的资产,称为 行为设计师。我极力推荐它。它非常适合不编写代码的游戏设计师,因此程序员可以研究机制,设计师将其放在角色的行为树上,使其无需编写代码即可根据需要工作。您可以在这里学习基础知识。
以下是 Hailga 的行为树:

这是一棵大树,但不要惊慌——这比看起来容易。
基本上,我们使用树开头的一些任务来设置战斗。例如,设置boss在第一阶段,播放介绍动画,并重置一些变量。

这些任务仅在战斗开始时运行,因此我们添加了一个具有实际老板行为的中继器,如下图所示。

老板的行为优先考虑的永远是健康。有了它,我们可以控制boss是否应该进入另一个阶段,甚至是否应该死亡。因此,我们首先询问boss的生命值是否超过75%。如果是这样,我们就运行第一阶段的任务,即冰尖刺、冰导弹和召唤雪泥(boss 小兵)。当boss的生命值低于75%时,树会转到图片底部的以下选择器,并运行第二阶段对应的任务,依此类推,直到boss到达最后阶段,角色以0生命值死亡。
在进入下一步之前,我想提一下外部行为树功能,这是一种组织像这样的大型行为树的很酷的方法。
您已经在上一张图片中看到了这些——带有三个框的图标是外部行为树。

将外部行为树视为代码中的方法:您在游戏所有逻辑的多个地方调用该方法,并且它在每个地方运行相同的代码,但只有一个地方有该代码。如果您必须更改该逻辑中的某些内容,则可以更改该方法的代码,并且它将在调用该方法的每个地方发生变化。在这里,它的工作原理是一样的。你有一个外部行为树,其中包含执行特定操作的行为,例如“召唤雪史莱姆”。
如果我进入我们的外部行为树,我会发现这个:

它就像一棵迷你行为树,检查boss不会重复同一种攻击太多次,并且战场上没有太多的仆从,然后召唤仆从,播放海尔加的语音,或者通过让boss处于空闲状态来完成。
如果我想改变战场上同时出现的仆从数量,我只需要在这个外部行为树中的“检查敌人类型数量”任务上进行更改,这将适用于用于召唤仆从的树的每个部分。
在创作 Hailga 时,我们的首席艺术家 Ruben Gómez 首先参考了现有角色,希望玩家能够认出他们。
在这种情况下,我们使用 《魔兽世界》 中的吉安娜(如上所述)和 《冰雪奇缘》 中的 艾尔莎 作为角色参考。
Ruben 是这样说的:
“考虑到这个前提,我从 Hailga 的设计开始,”鲁本说道。“我们从每个参考人物的衣服和发型中提取了一些特征,这些元素可能在一个非常小的像素化精灵中很容易被识别,其余部分则用想象力填充(没有人工智能,只是人类的想象力,和我小时候用的一样)。”

在制作动画的过程中,我们需要快速进行动作,但不能失去帧之间的平滑度,因此我们尝试通过更快的迭代来为每个角色的动作争取时间。我们总是从最终版本开始,使用最接近的插值对动画的每一帧的角色的每个部分进行裁剪、重新排列、缩放和旋转,目的是重复使用一些元素并避免抗锯齿。
之后,我们进行了快速的动作测试,并以同样的方式进行调整。

动画草稿完成后,我们完善每个元素,填补空白,并添加细节。
您可以在下图中看到每个帧的最终版本。

当动画还在制作中时,我继续测试和平衡 Boss 战。为此,我们创建了一个名为“战斗区”的场景,用它来测试老板、敌人、法术等。基本上,它是一个小区域,其中包含我们无需接触实际游戏即可测试的所有工具和功能。
当我们在战斗区场景中测试角色时,早期的 Hailga 头目是这样的:


最后,当我们对它的行为、功能和难度感到满意时,我们将 Hailga 整合到实际游戏中。

当我们完成 Hailga 的行为和动画后,我们开始使用 AnimatorImporter集成 Boss 的动画,这是一个用于集成在 Aseprite 中制作的像素艺术动画的绝佳工具。有了它,只需几个步骤就可以完成所有事情。
现在是时候给老板一些趣味了,这时我们的视觉特效艺术家 Teky 就开始发挥作用了。把它拿走吧,Teky:
嘿!Sergio Wajswol(又名这里是 Teky,他是 Evil Wizard 的程序员和视觉特效艺术家。
Hailga 的 VFX 确实很有挑战性,不仅因为它是团队的第一个 Boss,还因为它是我在游戏中的首要任务之一。在与 BOSS 的战斗中会使用多个视觉特效序列,每次攻击至少一个,但我只会关注其中的几个。
战斗中的高潮时刻之一是最后的阶段转换,海尔加变得愤怒并向邪恶巫师发射一道冰光束,让战场陷入冰冻。

我相信这是一个非常好的效果,可以将其拆开并展示出创造魔法的各个部分。为此,我们将过渡分为两个视觉特效部分:冰束和地板冻结。
对于第一件作品,我的工作在 Diego 完成攻击编程后就开始了,并且通常带有一个好看的占位符(在本例中是一个细长的矩形)——另外他还祝我好运。从这里开始,我开始使用我知道我工具箱中已有的工具。但由于开发才刚刚开始,所以我还缺少这些。过去,我曾使用 Unity 的 Line Renderer 组件 在通过脚本控制的任意两点之间渲染一条线,所以我从它开始,然后将它与一个基本的着色器结合起来,为线的边缘和中心添加颜色。

还没有完全实现,正如您上面看到的。我在 VFX 中很快理解的一点是(与传统哲学相反),“整体 是 部分的总和”。我的意思是可能需要多个系统才能达到预期的效果,而不仅仅是一个着色器或一个粒子。
接下来,我需要让效果看起来更像一束光束(并且不那么坚固),所以我使用 Shader Graph 来实现这一点。我将尽力简单解释这一点。
为了实现我的目标,着色器需要三个主要部分。首先,我使用了之前绘制的纹理,它只是一个水平镜像渐变(您可以在下图中看到它,即 MainTex)。通过使用节点“Pow”,我可以轻松控制光束的宽度(纹理会自我倍增,并且由于它是渐变的,所以会缩小光束)。

然后,我使用带有 Tiling And Offset 节点的 Simple Noise 动画来实现两个目的:
将光束分解在某些部分(始终由公共变量控制)
修改光束的 UV,使其看起来扭曲

继续,我将生成的光束与HDR颜色相乘,以控制发射的光辉。最后,我使用步进节点获取梁的边缘并将它们相乘以获得不同的颜色,使梁的中心脱颖而出。
一旦我完成了,我就可以像这样用不同的颜色和变量来玩。

这时我开始感觉自己似乎取得了一些进展,但我发现自己错过了一些东西:光束是从茫茫荒野中投射出来的。
因此,在粒子的帮助下,我制作了一个冰球,以便它可以作为光束的投射点:

最后,我们需要沿着光束的粒子将其整合到其余区域。

第二部分较短,但较为棘手。为了完成主要效果,我们需要能够在两种纹理(非冻结地板和冻结地板)之间进行插值,但要以径向角度跟随光束的轨迹和速度。
为了匹配速度,我们使用常规脚本来控制光束的速度,使之与 0 到 1 的变量一致,即根据光束的当前旋转,地板应该冻结多少。为了对纹理进行插值,我们需要一个短着色器。看看我们如何将着色器分成两部分以获得径向渐变和实际的线性插值。

下面是计算径向渐变的公式,其中考虑了 UV 位置并且精确地从 0 到 1。这使光束的运动与冻结值同步。

现场情况如下:

为了完成这个场景,我们把所有东西加在一起,实现了一个很酷的效果,既作为进入最后阶段的过渡,也是这个boss的攻击之一。
一切完成后,游戏作曲家 Haakon Davidsen添加了最后的润色——激动人心的音乐,让玩家感受到战斗的“热度”。您可以在这里听到。当然,配音演员—— 布里安娜·麦克道尔 (Breanna MacDowall)——为海尔加配音,表现出色。
我们希望您喜欢这个博客!
体验《邪恶巫师》中 Hailga 的 Boss 之战在 Steam 或 Xbox 上 – 并继续关注其在更多平台上的发布。点击此处,阅读直接来自开发人员的更多使用Unity制作的故事。
