由unity引擎做的游戏《缺氧》,它的地图的机制是怎么实现的?
由unity引擎做的游戏《缺氧》,它的地图的机制是怎么实现的? 有个老外对于解剖泰拉瑞亚做了很多出色工作,这是他的博客地形编辑器 Terrafirma - Mapping for Terraria
地表贴图uv分布 http://seancode.com/terrafirma/uvs.html
wld文件格式解析 http://seancode.com/terrafirma/world.html
github仓库 mrkite/TerraFirma terraria我也很喜欢,用unity做过类似他的demo,可以给你分享分享voxel 2d的一些心得:
1)tile 的定义
一般相同类型的tile都有多种,比如泥土地,可能有7-8中,每种周围可以凭借的方式也有很多种,还有泥土和草地,砂岩的拼接过渡tile,tile美术需要保证拼接是无缝的,然后就是有一种数据定义,用于定义什么tile可以和其他tile拼接,每个tile一般有8个方向,边缘的tile少1-2条边;
2)在unity里渲染
如果只是做demo,我推荐使用Mesh,基于一个chunk填充顶点数据,一个chunk大概16x16个tile,每个tile 16x16 像素 把所有tile合并进入一个贴图,减少批次,这里有一个技巧是,数据的准备可以多线程,最后在Mesh数据赋值是在主线程,可以分帧做,在快速移动相机时会很平滑,准备用的数据可以缓存,避免gc alloc;
如果做游戏,仔细优化,这部分我推荐做到low level render plugin里,完全在c代码里做,没有gc,快速计算tile;
如果是unity5.5以后,也可以考虑command buffer来做;
像terraria那样,需要大概5*5个tile或者7x7,随着相机移动,动态删除、创建新的chunk。
3)挖、补
挖、补去一个tile的时候,需要重新计算tile周围的填充,及计算新的顶点数据和uv
4)其他方面
流体,流体是terraira比较有意思的地方,困难的地方还是计算,我之前也是多线程计算才能效率比较高,否则非常影响渲染效率;
随机世界构建,这个经验不多,当初也没实现,这里我感觉是一些2d连续随机数+一些模式填充。
ps,terraria是c#写得,被人decompile,很多代码可以参考,csnxs/Terraria 最近写游戏涉及到了板块地图的绘制,正好来答一下
板块地图绘制的原理跟unity没什么关系
《缺氧》和《Terraria》的地图渲染方式还是有一点不一样的,我来解释一下(以下称“tile”为“块”)
每个块所使用的贴图都是与相关贴图无缝衔接的,如:
拼接起来是酱婶的:
在地形生成后,对于每个块都要检测一次“邻居块” (即该块周围八个方向上的块),来确定自己所处的边缘,记入自己的属性,渲染时再绘制对应的贴图
当添加或删除地图块时,也要对自身以及邻居地图块都要进行一次边缘检测来更新边缘属性
举个例子,从一个块的西北方顺时针进行检测,用“1”和“0”来代替泥土块的存在与否
检查结果为:11100011,就可以确定该块的贴图为
《Terraria》就是用类似上面介绍的方式来绘制地图
----------------------------------------------------------------------------
而在《缺氧》中,邻居块检测的结果只用于确定岩石块的不规则边缘的形状,然后对相同类型的岩石块用无缝衔接的大贴图以平铺的方式 blit 到区域内,有点类似于蒙版
用之前的例子表示就是:
最后就变成了
以上,biu~ 根据周边tile状态更换当前tile贴图,也就是说同种tile也需要做许多种可能的贴图,这种在中古时期的游戏中应用很多,甚至包括魔兽争霸。
具体游戏分析的话,格子的衔接统一采用了一个mask图片,可以看到按384切分成了多个状态的格子,根据生成地图格子中的同类衔接状态值选择mask切片,然后与原始的四方连续贴图融合即可。
另外格子种类的显示层级是固定的,比如沙土大于氧气等,那么整体衔接起来就会比较舒服了,而且只需要一个mask即可作为通用衔接图。
可参考我一篇分析,瓷砖贴图的过度
http://www.zhust.com/index.php/2016/10/关于瓷砖贴图的过渡(tile)/ 有人说了自动选取合适的tile来拼接。用的是这种 tile 。图源自 RPG Maker。RPG Maker 里就有这种功能,那里面叫 autotile。你装个 RPG Maker 试试就明白了。其实挺简单的。
这里面每个小格是16*16的,游戏中实际的tile是32*32的,是这里面四个小格拼成的。为了保证无缝,图案是每两个小格一循环。
如果让变化更丰富,可以对其中一些格子做变种,然后从变种里随机选取。 无缝拼接,之前偶然看见的一个基础版
《C++游戏开发》笔记十三 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法
页:
[1]