/// <summary> /// 批量平滑操作 /// </summary> public void BatchSmooth(Vector3[] centers, float radius, float dev, int level = 1) { float differx = terrainSize.x / (heightMapRes - 1) * level; float differz = terrainSize.z / (heightMapRes - 1) * level; int arrayLength = centers.Length; for (int i = 0; i < arrayLength; i++) { centers[i].x -= differx; centers[i].z -= differz; } Terrain[] terrains = new Terrain[arrayLength]; HMArg[] args = new HMArg[arrayLength]; //Loom.Initialize(); for (int i = 0; i < arrayLength; i++) { terrains[i] = InitHMArg(centers[i], radius, out args[i]); BatchSmooth(terrains[i], args[i].heightMap, args[i].startMapIndex, dev, level); //BatchSmoothAsync(terrains[i], heightMaps[i], mapIndexs[i], dev, level); } }
/// <summary> /// 初始化地形高度图编辑所需要的参数 /// 后四个参数需要在调用前定义 /// 编辑高度时所需要用到的参数后期打算用一个结构体封装 /// </summary> /// <param name="center">目标中心</param> /// <param name="radius">半径</param> /// <param name="mapIndex">起始修改点在高度图上的索引</param> /// <param name="heightMap">要修改的高度二维数组</param> /// <param name="mapRadius">修改半径对应的索引半径</param> /// <param name="limit">限制高度</param> /// <returns></returns> private Terrain InitHMArg(Vector3 center, float radius, out HMArg arg) { Vector3 leftDown = new Vector3(center.x - radius, 0, center.z - radius); // 左下方Terrain Terrain centerTerrain = Utility.SendRayDown(center, LayerMask.GetMask("Terrain")).collider?.GetComponent <Terrain>(); Terrain leftDownTerrain = Utility.SendRayDown(leftDown, LayerMask.GetMask("Terrain")).collider?.GetComponent <Terrain>(); arg = default(HMArg); if (leftDownTerrain != null) { // 获取相关参数 arg.mapRadiusX = (int)(heightMapRes / terrainSize.x * radius); arg.mapRadiusZ = (int)(heightMapRes / terrainSize.z * radius); arg.mapRadiusX = arg.mapRadiusX < 1 ? 1 : arg.mapRadiusX; arg.mapRadiusZ = arg.mapRadiusZ < 1 ? 1 : arg.mapRadiusZ; arg.startMapIndex = TerrainUtility.GetHeightmapIndex(leftDownTerrain, leftDown); arg.centerMapIndex = new Vector2Int(arg.startMapIndex.x + arg.mapRadiusX, arg.startMapIndex.y + arg.mapRadiusZ); arg.heightMap = GetHeightMap(leftDownTerrain, arg.startMapIndex.x, arg.startMapIndex.y, 2 * arg.mapRadiusX, 2 * arg.mapRadiusZ); arg.limit = 0 /*heightMap[mapRadius, mapRadius]*/; return(leftDownTerrain); } // 左下至少有一个方向没有Terrain,大多数情况下不会进入,如果删掉地图的左边界和下边界无法编辑,影响不大,其实我很想删掉,所以注释什么的就去TM的吧 else if (centerTerrain != null) { // 获取相关参数 arg.mapRadiusX = (int)(heightMapRes / terrainSize.x * radius); arg.mapRadiusZ = (int)(heightMapRes / terrainSize.z * radius); arg.mapRadiusX = arg.mapRadiusX < 1 ? 1 : arg.mapRadiusX; arg.mapRadiusZ = arg.mapRadiusZ < 1 ? 1 : arg.mapRadiusZ; arg.centerMapIndex = TerrainUtility.GetHeightmapIndex(centerTerrain, center); arg.startMapIndex = new Vector2Int(arg.centerMapIndex.x - arg.mapRadiusX, arg.centerMapIndex.y - arg.mapRadiusZ); int width = 2 * arg.mapRadiusX, height = 2 * arg.mapRadiusZ; if (arg.startMapIndex.x < 0 && arg.startMapIndex.y < 0) { if (centerTerrain.Left() != null) { height += arg.startMapIndex.y; arg.startMapIndex.y = 0; arg.startMapIndex.x += heightMapRes; centerTerrain = centerTerrain.Left(); } else if (centerTerrain.Bottom() != null) { width += arg.startMapIndex.x; arg.startMapIndex.x = 0; arg.startMapIndex.y += heightMapRes; centerTerrain = centerTerrain.Bottom(); } else { width += arg.startMapIndex.x; arg.startMapIndex.x = 0; height += arg.startMapIndex.y; arg.startMapIndex.y = 0; } } else if (arg.startMapIndex.x < 0) { width += arg.startMapIndex.x; arg.startMapIndex.x = 0; } else if (arg.startMapIndex.y < 0) { height += arg.startMapIndex.y; arg.startMapIndex.y = 0; } arg.heightMap = GetHeightMap(centerTerrain, arg.startMapIndex.x, arg.startMapIndex.y, width, height); arg.limit = 0 /*heightMap[mapRadius, mapRadius]*/; } return(centerTerrain); }