/// <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);
        }