/// <summary> /// 获取基础的地形树木(森林) /// </summary> /// <param name="random">随机对象</param> /// <param name="labyrinthStruct">迷宫结构</param> /// <param name="pixel">迷宫结构中每一个单位的宽度</param> /// <param name="size">地图的大小</param> /// <param name="maxHeight">地图最大高度</param> /// <param name="heightMaps">高度图</param> /// <param name="heightmapResolution">高度图分辨率</param> /// <param name="treePrototypes">返回一个树木心结数组</param> /// <returns></returns> private static TreeInstance[] GetDefaultTreeainTree_Forest( System.Random random, LabyrinthOutputStruct labyrinthStruct, int pixel, Vector2 size, float maxHeight, float[,] heightMaps, int heightmapResolution, out TreePrototype[] treePrototypes ) { treePrototypes = new TreePrototype[1]; TreePrototype treePrototype0 = new TreePrototype(); treePrototype0.prefab = Resources.Load <GameObject>("Tree/Tree1"); treePrototype0.bendFactor = 1; treePrototypes[0] = treePrototype0; //树木种下的偏差值 int x = labyrinthStruct.labyrinthData.GetLength(0); int y = labyrinthStruct.labyrinthData.GetLength(1); List <Vector3> posList = new List <Vector3>(); List <int> wallCounts = new List <int>(); for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { if (labyrinthStruct.labyrinthData[i, j] == LabyrinthPiecemealType.Wall) { int setTree = random.Next(0, 10); if (setTree > 2) { continue; } int wallCount = 0; if (i == 0 || labyrinthStruct.labyrinthData[i - 1, j] == LabyrinthPiecemealType.Wall) { wallCount++; } if (i == x - 1 || labyrinthStruct.labyrinthData[i + 1, j] == LabyrinthPiecemealType.Wall) { wallCount++; } if (j == 0 || labyrinthStruct.labyrinthData[i, j - 1] == LabyrinthPiecemealType.Wall) { wallCount++; } if (j == y - 1 || labyrinthStruct.labyrinthData[i, j + 1] == LabyrinthPiecemealType.Wall) { wallCount++; } wallCounts.Add(wallCount); float setX = NodiesTools.RandomRange(random.Next(0, 100), -0.5f, 0.5f, 0, 100); float setY = NodiesTools.RandomRange(random.Next(0, 100), -0.5f, 0.5f, 0, 100); posList.Add( new Vector3( ((i + 0.5f + setX) * pixel) / size.x, heightMaps[(int)((j + 0.5f + setY) / y * heightmapResolution), (int)((i + 0.5f + setX) / x * heightmapResolution)] - 0.1f, ((j + 0.5f + setY) * pixel) / size.y )); } } } int count = posList.Count; int treeTypeLength = treePrototypes.Length; TreeInstance[] results = new TreeInstance[count]; for (int i = 0; i < count; i++) { TreeInstance treeInstance = new TreeInstance(); treeInstance.position = posList[i]; float wallCount = wallCounts[i] * 0.1f; treeInstance.widthScale = (0.2f + NodiesTools.RandomRange(random.Next(0, 100), wallCount / 4, wallCount + 0.01f, 0, 100)) * pixel / 5f; treeInstance.heightScale = (0.2f + NodiesTools.RandomRange(random.Next(0, 100), wallCount / 4, wallCount + 0.01f, 0, 100)) * pixel / 5f; treeInstance.rotation = random.Next(0, 360); treeInstance.prototypeIndex = random.Next(0, treeTypeLength); treeInstance.color = new Color(1, 1, 1, 1); treeInstance.lightmapColor = new Color(1, 1, 1, 1); results[i] = treeInstance; } return(results); }
/// <summary> /// 获取基础的地形数据 /// 该地形仅仅包含基础的噪波信息 /// </summary> /// <param name="random">随机对象</param> /// <param name="labyrinthStruct">迷宫结构</param> /// <param name="maxHeight">最大高度</param> /// <param name="heightmapResolution">地图细节</param> /// <param name="pixel">迷宫结构中每一个单位的宽度</param> /// <returns></returns> private static float[,] GetDefaultTerrainHeightMap_Forest( System.Random random, LabyrinthOutputStruct labyrinthStruct, float maxHeight, int heightmapResolution, int pixel) { float[,] heightMaps = new float[heightmapResolution, heightmapResolution]; for (int i = 0; i < heightmapResolution; i++) { for (int j = 0; j < heightmapResolution; j++) { heightMaps[i, j] = 0.2f; } } //设置隆起位置 int xCount = labyrinthStruct.x; int yCount = labyrinthStruct.y; for (int i = 0; i < xCount; i++) { for (int j = 0; j < yCount; j++) { if (labyrinthStruct.labyrinthData[i, j] == LabyrinthPiecemealType.Wall) { int minX = (heightmapResolution * i) / xCount; int maxX = (heightmapResolution * (i + 1)) / xCount; int minY = (heightmapResolution * j) / yCount; int maxY = (heightmapResolution * (j + 1)) / yCount; for (int u = minX; u < maxX; u++) { for (int v = minY; v < maxY; v++) { heightMaps[v, u] += 0.7f; } } } } } //平滑 float[,] heightMaps_0 = (float[, ])heightMaps.Clone(); int l_max = (int)(pixel * 2f); Func <int, int, float, int> GetMinLength = (_x, _y, t) => { int _length = 1; ReCheck: for (int i = _x - _length; i <= _x + _length; i++) { if (i >= 0 && i < heightmapResolution) { if ((_y - _length >= 0 && heightMaps_0[i, _y - _length] < t) || (_y + _length < heightmapResolution && heightMaps_0[i, _y + _length] < t)) { goto BreakLine; } } } for (int i = _y - _length; i <= _y + _length; i++) { if (i >= 0 && i < heightmapResolution) { if ((_x - _length >= 0 && heightMaps_0[_x - _length, i] < t) || (_x + _length < heightmapResolution && heightMaps_0[_x + _length, i] < t)) { goto BreakLine; } } } _length++; if (_length < l_max) { goto ReCheck; } BreakLine: return(_length); }; for (int i = 0; i < heightmapResolution; i++) { for (int j = 0; j < heightmapResolution; j++) { if (heightMaps_0[i, j] > 0.5f) { int l_min = GetMinLength(i, j, 0.5f) * 2; l_min = l_min > l_max ? l_max : l_min; float l_f = NodiesTools.RandomRange(l_min, 0, 1, 0, l_max); float l_f_fade = NodiesTools.Fade(l_f); heightMaps[i, j] = Mathf.Lerp(0.2f, heightMaps_0[i, j], l_f_fade); } } } //获取噪波数组 float[,] nodies = NodiesTools.TwoDPerlinNodies( random, heightmapResolution, heightmapResolution, new int[] { pixel, pixel / 2, pixel / 3 }, new int[] { pixel, pixel / 2, pixel / 3 }, new float[] { 0.1f, 0.05f, 0.02f }); //将噪波添加上去 float offset = 10 / maxHeight; for (int i = 0; i < heightmapResolution; i++) { for (int j = 0; j < heightmapResolution; j++) { heightMaps[i, j] += nodies[i, j] * offset; } } return(heightMaps); }