声明:部分原理与代码取自链接:https://blog.csdn.net/xdedzl/article/details/85268674
首先了解一下,Unity的地形系统Terrain的地形相关数据是存放在TerrainData里的
而关于地形的高低起伏数据,是存储在TerrainData中的HeightMap中。
通常在新建地形的时候,我们就已经确定了HeightMap的分辨率
高度图的分辨率即精度,精度越高地形可变粒度就越高,高低起伏就越平滑。
而我们要修改地形,也是通过修改这个HeightMap来实现的。
弹坑说明
根据上图可以看出,想要创造一个弹坑,首先确定的是爆炸中心(centerPosition)和弹坑半径(radius),通过这两个条件,可以确定我们到底要获取高度图的哪一块进行编辑。
TerrainData本身提供了GetHeights方法:
// 摘要:
// Get an array of heightmap samples.
//
// 参数:
// xBase:
// First x index of heightmap samples to retrieve.
//
// yBase:
// First y index of heightmap samples to retrieve.
//
// width:
// Number of samples to retrieve along the heightmap's x axis.
//
// height:
// Number of samples to retrieve along the heightmap's y axis.
public float[,] GetHeights(int xBase, int yBase, int width, int height);
可以了解到参数是需要高度图起点的x,y值和获取区域的长宽
所以爆炸中心的位置(centerPosition)是无法直接做参数使用的,我们需要先算出左下起点(LeftBottomPosition)位置
Vector3 LeftBottomPosition = centerPosition - new Vector3(radius,0, radius);
接着计算出起点(LeftBottomPosition)与地形(item)的相对位置
//起点相对地形坐标位置
Vector3 tLocalPos = LeftBottomPosition - item.transform.position;
再使用高度图的精度和地图的长宽进行计算,将起点位置转化为高度图坐标位置(dPos)
TerrainData td = item.terrainData;
Vector2 dPos = new Vector2(tLocalPos.x/td.size.x*td.heightmapResolution,tLocalPos.z/td.size.z*td.heightmapResolution);
最后,将弹坑直径转换成高度图长度,所有的参数就得到了,通过GetHeights方法得到需要修改的原高度信息float[,]
得到了原始数据接下来考虑的就是如何修改它,相关的方法有各种各样,我使用的是类似unity地形自带的笔刷效果,通过一张α通道的图片来控制各个位置与初始位置的偏离
因为需要实现的效果如下图