- 0
- 0
- 0
分享
- 资深技术游戏设计师,教你如何在游戏里“玩转”一团火
-
原创 2022-06-09
想要打造丰富有趣的游戏体验,也许并不需要多么高深复杂的技术与编程,在资深游戏设计师的手中,通过合理的规划与高超的技巧,只需要几个简单的脚本就能制作出高交互性的游戏系统,实现涌现式的结果,让游戏体验出人意料、妙趣横生。
我们新推出了一门免费教程《Unity游戏设计师实操手册》,帮助用 Unity 设计、制作和测试游戏的设计师们掌握更多 Unity 的使用技巧,相信新手老手都能有所收获,该教程由资深技术游戏设计师 Christo Nobbs 参与编写。
本篇文章,我们邀请到了 Christo Nobbs 来介绍几种用 Unity 功能来设计涌现式游戏玩法(Emergent game design)。
在游戏设计中,实用性强的系统应该具备明确的功能、可存储数据,并带有模块化的特征。这样一来,系统不仅能与其他系统互动,还能借助其他游戏对象改变自己的状态。在构思一个游戏系统时,我们不一定需要将其视作一个完整的架构,而可以把它看作一个个不停影响游戏的功能。
通过结合这些系统,我们可以创造出与玩家行为相互作用的独特系统生态,再借助“设计控制杆”(而不是那种藏在脚本里的硬编码数值)进行平衡。设计师将使用这些控制杆来调整参数,产生系统性的改变。
大多数游戏都会有至少一个系统,它可以是带有可调参数的单一游戏机制,也可以是由多个系统交织成网的。在类似《帝国时代》等战略游戏中 ,玩家必须学会通过控制资源来制约并击败对手,这就是复杂系统生态影响游戏进程的例子之一。
但说到底,游戏的推进方式要由设计者自己来决定。我们可以将游戏设定成一个受控的线性叙事故事,也可以让一个或多个系统有机结合,来产生涌现式的结果。
模块化系统催生出的有趣玩法
在设计一个小系统时,我们应优先考虑系统的模块性以及与其他系统的衔接能力,由独立又相互作用的系统来驱动有趣的游戏逻辑。我们可以设想某个系统在另一个物体的作用下,与自己相撞会产生怎样的连环反应,或者用两个相互对抗的简单系统来创造一个游戏环境。这里,每个系统的功能都必须能被玩家清晰理解,让玩家有机会了解并利用这些系统互动。
Klei的《缺氧》
《缺氧(Oxygen Not Included)》是连锁反应的一个好例子,游戏的主目标是平衡各个系统、营造一个互相共存的乌托邦来不断推进游戏。另一个例子是拉瑞安工作室的《神界:原罪 2(Divinity Original Sin 2)》, 游戏中某些小怪在受到攻击后会产生爆炸,如果玩家通过水桶、祈雨等手段淋湿它们,就可以避免爆炸、让战斗变得更轻松。或者玩家也可以用火焰法术点燃地面,并阻止怪物靠近。
模块化系统的小部分功能甚至可用来打造另一个系统,为游戏带来更多的可玩价值。
Christo 非常推崇的一个 Unity 功能是 Animation Curves(动画曲线)。他说:“动画曲线的数据处理有统一的方法,并且相比于参数它能实现更精细的控制。我们既可以减缓某种机制的运行,也能让系统‘超频’,借此反复调试某些细节。”
模块化的设计方法还能让我们更准确地向程序员介绍系统,让后者能更高效地编辑和调试,或调整系统配置,将其重复使用。
设计控制杆
用设计控制杆来调整游戏难度等参数有助于提高游戏运行结果的趣味性、调试出想要的游戏复杂度。我们可以反复测试和调整,直到取得理想的结果。
设计控制杆的使用可以贯彻整个游戏开发,从游戏概念设计和原型阶段,一直到后期的精细打磨阶段。Christo 就表示自己在用流程图描绘想法时,经常加入设计控制杆。我们需要尽量在项目初期就考虑好要加哪些开关和控制杆,方便后期的游戏调试、探索游戏的各种可能性,避免大量地重写代码。
在下方的流程图中,敌人的出生点在 Start 处,玩家在进入流程时就装载好了武器。本来玩家必须杀死敌人,但我们可以利用控制杆来改变游戏的玩法、转移游戏焦点。在一种配置下,游戏玩法可变为赚取高分、在限定时间内快速杀死敌人;而在另一种配置中,游戏玩法可转变为在限定时间内杀死一定数量的敌人,再留下一点时间捡取战利品并撤离。
简单的玩法设计
这种系统也可用于制作带有强力掉落物和多种子弹类型的“子弹地狱”类游戏,通过加入诸如限时重生等更多的设计控制杆,我们就能进一步扩展该系统。
《逃离塔科夫》中的武器制作系统
Battlestate Games 的《逃离塔科夫(Escape from Tarkov)》是另一个在 Unity 里系统性设计游戏的例子。游戏里有一个制作系统,可用于制作带有独特数据的武器,如下图。这套数据将决定枪的特性和玩法,与之相似的还有玩家的健康状况。如果玩家惨遭断肢或染上疾病,角色会变得难以使用枪械,而健康的玩家则能更好地控制武器。
《逃离塔科夫》中的武器制作系统
武器系统与生命系统间的关系鼓励玩家不仅要珍惜自己的生命,还要珍惜高性能的武器。没人想用一支没有防尘罩或枪托、准心跳来跳去的AK步枪,这种配置的武器很明显是一个糟糕的选择。
游戏中还有大量带有不同特性的弹药种类及护甲。玩家必须判断对手带的是什么弹药和护甲,找出针对性的攻击策略来最大化伤害,这就形成了一种相生相克的游戏规则。每个系统都有自己的视觉元素,游戏的设计师们通过平衡这些系统来创造出他们眼中的游戏“精髓”。
将可编程对象用作“控制杆”
在 Unity 中加入设计控制杆的另一种方法是善用 ScriptableObject。ScriptableObject 可用作数据的容器,并作为单独的资源在脚本中引用,避免让脚本依赖其他场景对象。
我们可以创建多个 ScriptableObject 资源、保存多个参数集,通过共享和交换数值来改变整块游戏体验,其作用类似于预设。运行模式下所做的修改将被保存到 ScriptableObject,所以无须在退出后根据笔记再次修改。
比如在设计某角色的原型时,我们可以将 ScriptableObject 替换成另一个带有不同数值的对象来改变角色的设计。这是一种制作 BUFF/DEBUFF 原型或将特定角色保存至某个存档的可行方法。
假设正在制作一款射击游戏,并且已经做出了一个枪支系统,其中的后坐力、射速、精确度、射击模式、音频设置、VFX 设置等强制行为具备一定的随机性。我们可以先新建任意数量的新枪支配置,在运行模式下调整其设置,然后一次性保存所有的改动。这些预设好的 ScriptableObject 可在团队成员之间传递,并搜集反馈来找出对的游戏感觉。
设计控制杆可作为公开属性来控制脚本的某个变量,变量的浮点或整数范围可用 Unity 的 RangeAttribute(范围特性)限制,然后作为滑动条显示在 Inspector 窗口中。这样做的目的是在项目打开期间调整变量,让编辑模式下的修改或工具测试也能调整变量,而非仅仅是在运行模式下。
相比于其他游戏类型,生存游戏的玩家更期望他们的行动选择和最终结局是合乎逻辑且开放式的,并在此之间找出每个挑战的解决办法。那怎样才能设计出这种兼具挑战和对策的涌现式系统呢?
让我们看看一种玩家需要待在特定区域才能存活的例子,比如 Klei 工作室的《饥荒》。玩家造出的篝火可以阻止附近敌人进攻,也可以用来烹饪食物或保暖。但玩家角色、食物或易燃物在离火焰过近时也会被点燃。
那什么样的系统才能产生上述的连锁反应呢?可以用一个体积(Volume)来逐渐加热附近的玩家角色,或者编写一个连续性的火焰蔓延系统。但何不以一种以系统为中心的角度来实现这种效果呢?我们可以让可燃物相互之间或与其他系统碰撞产生连锁反应,迫使玩家应对这种复杂的情形。
我们可以建立一个池塘生态系统,在其周围的固定区域内种下树木,树木在发芽生长后会逐渐占据整个空间。等到他们完全长成时,就可以砍倒作为木材。
玩家能用木材建造花哨的木椅等物品,或用来在池塘边生起一团小篝火,温暖、烘干游泳后的玩家。但如果玩家有了点燃篝火的能力,会发生什么?
具备简单燃烧系统的木头,在燃烧时会向半径范围内持续散发热量,当热量超过了附近木制物品或树木的燃点,就会着火。因此,玩家在点燃篝火时也就等于点燃了自己的木椅,要想挽救椅子,玩家必须把它扔到水里去。但这时火又把附近的树点着了,火势越来越大最终形成了森林大火。
即使是这种迷你、有限的系统也能为玩家提供有趣和“无脚本”体验。另外,不能一味地还原真实,必须把重点放在游戏性上,这样才能产生意外诡谪的乐趣。
在本例中,可以把这个“系统开关”存为一个 ScriptableObject,添加到任何可燃物上,为突发事件埋下伏笔。
我们首先来看看这么一个世界:水边有一棵枯树已经在燃烧,树向着水面倾斜,而玩家需要取暖。本例中的树木就带有一个储存多种燃烧相关参数的 ScriptableObject。
具体来看这些参数。
Default Temprature(默认温度):不受全局状态影响时的占位值。假定所有树木都带有燃烧系统,则整个生态环境会随着全局气温的高低而改变,高温下树林将极易产生火灾。
Current Temperature(当前温度):物品加热或冷却时的温度,它决定了对象是否在燃烧(当前温度是否超过燃点)。
Combustion Temperature(燃烧温度):对象燃烧必须达到的温度。
Heatup Rate(发热率):对象在某热源影响半径内的升温速度。
Cooldown Rate(冷却率):对象恢复到“冷却”温度的速度,可以称为恢复率(retention)或热量(thermal quality),这个名称只要表意即可。
Burn Rate(燃烧率):对象在时间段内的燃烧速度。
Fuel(燃烧质量):对象带有多少可燃烧的质量。
Heat Strength(加热强度):燃烧半径内的发热程度。
Heat Radius(散热半径):热量扩散的范围。
外加上一些配套的游戏逻辑,就可以让燃烧物旁的物体着火了。我们可以先存储原型的配置,然后不停试验,直到找到突破点,然后定下这些属性值。
这里的水并没有阻挡火焰的机制,但火焰在没有其他可燃物的情况下也不能蔓延到另一边,除非再加入一个新系统。
本例中的火焰蔓延系统所带有的燃烧质量、燃烧速度和加热强度等多种参数,能以多种方式产生同样的结果。我们还可以用新的参数来产生新结果,比如用“血量”替换“燃烧质量”,让树在经受一定的伤害后倒下,同时保留控制杆的功能。当一棵树的血量变低,其倒下的概率也将大幅增加。当周围布满了可燃物时,燃烧中的低血量树木在倒下后会将四周化作一片火海,除非玩家做点什么。
在环境中加入更多类似的系统,就能得到一个可以多系统相互作用的生态。假设玩家用采集的木材建造和制作了物品,这些物品继承了燃烧系统搞不好就会成为定时炸弹!
我们也能降低燃点阈值、提高加热速率来创造一个极不稳定的可燃环境,使对象更容易着火。增加散热半径来让火焰扩撒地更快、更不可控。将 Heatup Rate 限制在0到50之间可让火焰逐渐地扩散;这个值可以乘上 Heat Strength,但必须保持在一个合理范围内。如果 Strength 为4,则 Heatup Rate 将被放大成0到200,如此高的热量会在几秒钟内引发一场森林大火。此时的玩家无法及时灭火,游戏体验也会变差。
如若将燃点阈值提高到 300,这个系统便会更加平衡。玩家在火灾发生前会有足够的时间完成其他任务,在火苗大范围扩散的初期及时地控制住火势。尤其是当游戏具有砍树、建造障碍物等功能,或有简单的水系统时。
我们还可以进一步扩展火焰蔓延系统,为散热半径内的对象加上一个抗燃烧值。这样几片起火的区域可以有不同温度,游戏中也可以加入防火涂层等类似的升级。这可能过于复杂了,但通过这样系统地构思游戏,处在冰冻森林中的玩家将有机会利用燃烧系统提高存活的可能性。
火焰蔓延系统的例子表明单一的线性机制也能转化为有趣的游戏性,让玩家在学习和理解游戏系统的过程中探索出问题的解决方案。并且如果我们不强调系统的写实感,就不必再去思索额外的复杂度和抽象概念了。
本文借助这个简单的例子探讨了如何用模块化、交互式的简单小系统来形成一个更大的游戏世界生态,用控制杆来平衡游戏,搜集他人意见来改进和迭代游戏。这些元素能为玩家带来意想不到的乐趣、喜悦和悬念,有助于让游戏成为真正独特的体验。
点击“阅读原文”或通过以下链接,即可学习免费教程《Unity游戏设计师实操手册》。
长按关注
第一时间了解Unity引擎动向,学习最新开发技巧
-
阅读原文
* 文章为作者独立观点,不代表数艺网立场转载须知
- 本文内容由数艺网收录采集自微信公众号Unity官方平台 ,并经数艺网进行了排版优化。转载此文章请在文章开头和结尾标注“作者”、“来源:数艺网” 并附上本页链接: 如您不希望被数艺网所收录,感觉到侵犯到了您的权益,请及时告知数艺网,我们表示诚挚的歉意,并及时处理或删除。