Notifications
Article
在Unity中为即时战略游戏实现战争迷雾(上)
Updated 6 days ago
719
3
本文将由游戏开发工程师Ariel Coppes分享在Unity中为即时战略游戏实现战争迷雾效果。
过去三年中,我一直在Ironhide Game Studio开发移动即时战略游戏《钢铁战队》。在开发过程中,我实现了适合这款游戏的战争迷雾效果,但该实现方法缺乏即时战略游戏中的一些常见功能,我希望有一天能够找到改进它的方法。
最近,我在拳头游戏开发博客阅读到了一篇关于《英雄联盟》中战争迷雾实现方法的文章,我从中得到了很多启发,于是开始构思新的实现方法。
本文,我将详解《钢铁战队》中战争迷雾效果的实现方法。下一篇文章,我会介绍新的实现方法,解释为什么该方法比之前的方法更好。

战略游戏中的战争迷雾

战争迷雾通常表现战场上的未知信息和过期信息,例如:关于地形的未知信息,敌人基地的原先位置信息。玩家单位和建筑会提供视野,移除战争迷雾,展示关于地形的信息、当前位置和敌人的状态。
如下图所示,在《沙丘2》中,战争迷雾效果展示了未知区域。
下图是《魔兽争霸:人类与兽人》中的战争迷雾。
战争迷雾的概念已经在策略类游戏中使用了超过20年的时间,影响了大量的游戏。

开发过程

在开始实现前,我研究了一些游戏的效果,并决定我想要的效果。在完成研究后,我决定使用类似《星际争霸》的实现方法。
在《星际争霸》中,游戏里的单位和建筑会给玩家提供一定范围内的视野。未探索的区域覆盖着不透明的黑色迷雾,之前探索过的区域会覆盖半透明的迷雾,显示玩家已经了解的地形等信息,这类信息在游戏期间往往不会发生变化。
敌人单位和建筑仅在进入玩家视野时可见,但建筑在离开视野后会留下最后的已知位置。
我认为这是因为建筑通常无法移动(《星际争霸》的人族建筑是例外),因此通常可以认为在失去视野后,建筑依旧留在远处,这是战场上的重要信息。

《钢铁战队》

确定这些规则后,我创建了模拟图,用于在开发前确定想要呈现的游戏内效果。
模拟图1:在《钢铁战队》中,测试不同战争迷雾下的地形。
模拟图2:测试敌人单位确定可见时间。
我首先构造逻辑原型,了解该效果是否适合我们的游戏,并确定改进的方法。
为此,我使用int矩阵来表示游戏世界中玩家视野的离散数值形式。矩阵中的0表示玩家在该位置没有视野,1或更大数值表示该位置有视野。
如下图所示,在矩阵中有3块视野,其中1块有更大的范围。
游戏单位和建筑的视野会给数值增加1,表示该世界位置在玩家的视野范围之内。每次移动时,首先在原有位置减小1,然后在新的位置增加1。
我们为每个玩家提供了类似的矩阵,用于显示和隐藏敌人单位和建筑,该矩阵也会提供给无法在视野外开火的自动瞄准目标的技能。
为了决定敌人单位或建筑是否可见,我们首先通过变换世界位置,获取对应的矩阵部分,然后检查存储的数值是否大于0。
如果不大于0的话,我们会把游戏对象图层改为从主摄像机中剔除的部分,来避免对其进行渲染,我们把相应图层命名为“Hidden”。如果是可见的话,我们会把该图层改为默认图层,使它开始进行渲染。
下图展示敌人单位不在游戏视图中渲染的效果。

视觉效果

首先,我们会在游戏世界为每个矩阵部分渲染黑色或灰色的四边形,下图是相应的渲染效果。
我们可以使用该效果构造原型,决定我们不需要的内容。例如,我们不想让山和树等障碍阻挡视野,因为我们希望避免有视野受限的感觉,而且我们不希望像其它游戏一样,在游戏中使用多个层级的地形。
在确定内容和在游戏内进行测试后,我们决定开始改进视觉实现方法。
改进的版本可以在整个游戏世界中渲染带有战争迷雾的纹理,它和我们制作视觉模拟图的方法类似。
为此,我们创建了带有MeshRenderer组件的游戏对象,然后调整其大小,使它覆盖整个游戏世界。该网格会渲染名称为FogTexture的纹理,其中包含迷雾信息,该网格的着色器会把像素颜色视为反向的Alpha通道,白色表示完全透明,黑色表示完全不透明。
为了填补FogTexture纹理,我们创建了单独的摄像机,名称为FogCamera,它会使用RenderTexture渲染纹理,把画面渲染到纹理上。
对于游戏中提供视野的每个对象,我们都在FogCamera对象中创建了相应的游戏对象,根据视野的范围来变换位置并进行缩放。我们使用了被其它摄像机剔除的独立Unity层,让FogCamera来渲染这个层中的游戏对象。
为了完成这个过程,每个对象都有SpriteRenderer组件,组件上有白色的小椭圆纹理,可以用来在RenderTexture渲染纹理中渲染白色像素。
请注意:为了模拟游戏视角,我们使用的是椭圆形,而不是圆形。
这是每个视野使用的纹理,它是带有透明度的白色椭圆形。在此,我把透明部分改为不透明的白色,以便读者可以查看。
下面是游戏对象和FogCamera对象的示例。
为了让FogTexture在游戏过程中有平滑的效果,在渲染到RenderTexture渲染纹理时,我们对FogCamera对象应用了少量模糊效果。
我们测试了不同的模糊着色器和配置,最后找到适用于多款移动设备的着色器。下面是该脚本组件的截图。
下图是迷雾在游戏内的效果,第一张图没有模糊效果,第二张图有模糊效果。
为了渲染已探索的区域,我们要在之前加一步。在该步骤中,我们配置了另一个摄像机,名称为PreviousFogCamera,它也会使用RenderTexture渲染纹理,该渲染纹理名称为PreviousVisionTexture,我们使用相同的过程在此渲染视野。
该步骤的主要区别是:新的摄像机使用了“Don’t Clear”清理标识,不会清理缓冲区。因此,我们可以保留之前画面的数据。
此后,我们会使用FogCamera对象,渲染灰色部分的PreviousVisionTexture纹理和FogTexture纹理中视野的对象,最终结果如下图所示。
下图是在FogCamera对象中展示已探索的区域。
下图显示已探索区域与迷雾在游戏内的外观效果。

建筑

由于《钢铁战队》中的建筑较大,而且不会像《星际争霸》的建筑那样移动,因此我们打算使用类似的实现方法。
为此,我们对迷雾下我们想要显示的建筑添加组件,并设置为在建筑离开玩家视野时,让其继续进行渲染。
我们还有一个系统,在带有之前组件的对象首次进入玩家视野时,该系统会创建另一个对象,并进行相应的配置。
当建筑不再处于玩家视野时,该对象会自动启用,当建筑处于视野内时,它会自动禁用。如果该建筑在视野外被摧毁,该对象也不会立即消失,直到玩家查看到该对象的新状态。
在进入和离开玩家视野时,我们加入了简单的过渡效果,使该过程看起来更平滑。下面的图片展示了该过程的效果。

小结

虽然本文的实现方法缺少一些常见的战争迷雾功能,但它很适合我们的游戏,外观也很不错,这种方法在移动设备上的运行效果很好,我们对《钢铁战队》开发中所实现的成果感到非常骄傲和高兴。
本文就是我为《钢铁战队》实现战争迷雾的方法,希望开发者能够喜欢这种方法。下一篇文章中,我将介绍包含更多功能的新方法。
开发过程中遇到问题?请在App”群聊“ - “技术交流”中提问。
文章来源:gemserk.com
Tags:
Unity开发者原创
17
Comments
好赞,学习了
0
l
long
6 days ago
能放出点码来就更好了😁
2
Johnson
6 days ago
Get
0