public static void MassPlaceTrees(TerrainData terrainData, int numberOfTrees, bool randomTreeColor, bool keepExistingTrees) { int length = terrainData.treePrototypes.Length; if (length == 0) { Debug.Log("Can't place trees because no prototypes are defined"); } else { Undo.RegisterCompleteObjectUndo(terrainData, "Mass Place Trees"); TreeInstance[] sourceArray = new TreeInstance[numberOfTrees]; int num2 = 0; while (num2 < sourceArray.Length) { TreeInstance instance = new TreeInstance { position = new Vector3(UnityEngine.Random.value, 0f, UnityEngine.Random.value) }; if (terrainData.GetSteepness(instance.position.x, instance.position.z) < 30f) { instance.color = !randomTreeColor ? Color.white : GetTreeColor(); instance.lightmapColor = Color.white; instance.prototypeIndex = UnityEngine.Random.Range(0, length); instance.heightScale = GetTreeHeight(); instance.widthScale = !lockWidthToHeight ? GetTreeWidth() : instance.heightScale; instance.rotation = GetTreeRotation(); sourceArray[num2++] = instance; } } if (keepExistingTrees) { TreeInstance[] treeInstances = terrainData.treeInstances; TreeInstance[] destinationArray = new TreeInstance[treeInstances.Length + sourceArray.Length]; Array.Copy(treeInstances, 0, destinationArray, 0, treeInstances.Length); Array.Copy(sourceArray, 0, destinationArray, treeInstances.Length, sourceArray.Length); sourceArray = destinationArray; } terrainData.treeInstances = sourceArray; terrainData.RecalculateTreePositions(); } }
private void ApplyTextures(TerrainData terrainData) { var flatSplat = new SplatPrototype(); var steepSplat = new SplatPrototype(); flatSplat.texture = Settings.FlatTexture; steepSplat.texture = Settings.SteepTexture; terrainData.splatPrototypes = new SplatPrototype[] { flatSplat, steepSplat }; terrainData.RefreshPrototypes(); var splatMap = new float[terrainData.alphamapResolution, terrainData.alphamapResolution, 2]; for (var zRes = 0; zRes < terrainData.alphamapHeight; zRes++) { for (var xRes = 0; xRes < terrainData.alphamapWidth; xRes++) { var normalizedX = (float)xRes / (terrainData.alphamapWidth - 1); var normalizedZ = (float)zRes / (terrainData.alphamapHeight - 1); var steepness = terrainData.GetSteepness(normalizedX, normalizedZ); var steepnessNormalized = Mathf.Clamp(steepness / 1.5f, 0, 1f); splatMap[zRes, xRes, 0] = 1f - steepnessNormalized; splatMap[zRes, xRes, 1] = steepnessNormalized; } } terrainData.SetAlphamaps(0, 0, splatMap); }
void FillAlphaMap(TerrainData terrainData) { float[,,] map = new float[m_alphaMapSize, m_alphaMapSize, 2]; Random.seed = 0; for(int x = 0; x < m_alphaMapSize; x++) { for (int z = 0; z < m_alphaMapSize; z++) { // Get the normalized terrain coordinate that // corresponds to the the point. float normX = x * 1.0f / (m_alphaMapSize - 1); float normZ = z * 1.0f / (m_alphaMapSize - 1); // Get the steepness value at the normalized coordinate. float angle = terrainData.GetSteepness(normX, normZ); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. float frac = angle / 90.0f; map[z, x, 0] = frac; map[z, x, 1] = 1.0f - frac; } } terrainData.alphamapResolution = m_alphaMapSize; terrainData.SetAlphamaps(0, 0, map); }
private void ApplyTextures(TerrainData data) { var flatSplat = new SplatPrototype(); var steepSplat = new SplatPrototype(); flatSplat.texture = Settings.FlatTexture; steepSplat.texture = Settings.SteepTexture; data.splatPrototypes = new [] { flatSplat, steepSplat }; data.RefreshPrototypes(); var splatMap = new float[data.alphamapResolution, data.alphamapResolution, 2]; for (var z = 0; z < data.alphamapHeight; z++) { for (var x = 0; x < data.alphamapWidth; x++) { var normalizedX = (float)x / (data.alphamapWidth - 1); var normalizedZ = (float)z / (data.alphamapHeight - 1); var steepness = data.GetSteepness(normalizedX, normalizedZ) * Settings.SteepnessTextureMultiplier; var steepnessNormalized = Mathf.Clamp(steepness, 0, 1f); splatMap[z, x, 0] = 1f - steepnessNormalized; splatMap[z, x, 1] = steepnessNormalized; } } data.SetAlphamaps(0, 0, splatMap); }
public static void MassPlaceTrees(TerrainData terrainData, int numberOfTrees, bool randomTreeColor, bool keepExistingTrees) { int length = terrainData.treePrototypes.Length; if (length == 0) { Debug.Log((object) "Can't place trees because no prototypes are defined"); } else { Undo.RegisterCompleteObjectUndo((UnityEngine.Object) terrainData, "Mass Place Trees"); TreeInstance[] treeInstanceArray1 = new TreeInstance[numberOfTrees]; int num = 0; while (num < treeInstanceArray1.Length) { TreeInstance treeInstance = new TreeInstance(); treeInstance.position = new Vector3(UnityEngine.Random.value, 0.0f, UnityEngine.Random.value); if ((double) terrainData.GetSteepness(treeInstance.position.x, treeInstance.position.z) < 30.0) { treeInstance.color = (Color32) (!randomTreeColor ? Color.white : TreePainter.GetTreeColor()); treeInstance.lightmapColor = (Color32) Color.white; treeInstance.prototypeIndex = UnityEngine.Random.Range(0, length); treeInstance.heightScale = TreePainter.GetTreeHeight(); treeInstance.widthScale = !TreePainter.lockWidthToHeight ? TreePainter.GetTreeWidth() : treeInstance.heightScale; treeInstance.rotation = TreePainter.GetTreeRotation(); treeInstanceArray1[num++] = treeInstance; } } if (keepExistingTrees) { TreeInstance[] treeInstances = terrainData.treeInstances; TreeInstance[] treeInstanceArray2 = new TreeInstance[treeInstances.Length + treeInstanceArray1.Length]; Array.Copy((Array) treeInstances, 0, (Array) treeInstanceArray2, 0, treeInstances.Length); Array.Copy((Array) treeInstanceArray1, 0, (Array) treeInstanceArray2, treeInstances.Length, treeInstanceArray1.Length); treeInstanceArray1 = treeInstanceArray2; } terrainData.treeInstances = treeInstanceArray1; terrainData.RecalculateTreePositions(); } }
public static void MassPlaceTrees(TerrainData terrainData, int numberOfTrees, bool randomTreeColor, bool keepExistingTrees) { int num = terrainData.treePrototypes.Length; if (num == 0) { Debug.Log("Can't place trees because no prototypes are defined"); return; } Undo.RegisterCompleteObjectUndo(terrainData, "Mass Place Trees"); TreeInstance[] array = new TreeInstance[numberOfTrees]; int i = 0; while (i < array.Length) { TreeInstance treeInstance = default(TreeInstance); treeInstance.position = new Vector3(UnityEngine.Random.value, 0f, UnityEngine.Random.value); if (terrainData.GetSteepness(treeInstance.position.x, treeInstance.position.z) < 30f) { treeInstance.color = ((!randomTreeColor) ? Color.white : TreePainter.GetTreeColor()); treeInstance.lightmapColor = Color.white; treeInstance.prototypeIndex = UnityEngine.Random.Range(0, num); treeInstance.heightScale = TreePainter.GetTreeHeight(); treeInstance.widthScale = ((!TreePainter.lockWidthToHeight) ? TreePainter.GetTreeWidth() : treeInstance.heightScale); treeInstance.rotation = TreePainter.GetTreeRotation(); array[i++] = treeInstance; } } if (keepExistingTrees) { TreeInstance[] treeInstances = terrainData.treeInstances; TreeInstance[] array2 = new TreeInstance[treeInstances.Length + array.Length]; Array.Copy(treeInstances, 0, array2, 0, treeInstances.Length); Array.Copy(array, 0, array2, treeInstances.Length, array.Length); array = array2; } terrainData.treeInstances = array; terrainData.RecalculateTreePositions(); }
/// <summary> /// Generate trees on the terrain /// </summary> List<TreeInstance> GenerateTrees(TerrainData data, int tileX, int tileZ) { //make sure prototypes have been set if (_treePrototypes.Length < 1) { return null; } var trees = new List<TreeInstance>(); int spacing = 8; var maxHeight = _terrainSettings.TerrainHeight * 0.7f; var minHeight = _terrainSettings.TerrainHeight * 0.1f; for (var x = 0; x < _terrainSize; x += spacing) { for (var z = 0; z < _terrainSize; z += spacing) { var unit = 1.0f / (_terrainSize - 1); var offsetX = Random.value * unit * spacing; var offsetZ = Random.value * unit * spacing; var xNorm = x * unit + offsetX; var zNorm = z * unit + offsetZ; var xWorld = x + tileX * (_terrainSize - 1); var zWorld = z + tileZ * (_terrainSize - 1); //randomizes the spacing spacing = Random.Range(4, 12); // Get the steepness value at the normalized coordinate. var angle = data.GetSteepness(xNorm, zNorm); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. var frac = angle / 90.0f; if (frac < 0.7f) { var noise = _treeNoise.FractalNoise2D(xWorld, zWorld, 3, _terrainSettings.TreeFrequency, 1.0f); var height = data.GetInterpolatedHeight(xNorm, zNorm); //no trees on high mountains if (noise > 0.1f && height < maxHeight && height > minHeight) { //Create the tree instance var tree = new TreeInstance() { heightScale = 1, widthScale = 1, prototypeIndex = Random.Range(0, _treePrototypes.Length), lightmapColor = Color.white, color = Color.white, position = new Vector3(xNorm, height, zNorm) }; trees.Add(tree); } } } } return trees; }
/// <summary> /// Generate detail like grass and props on the terrain /// </summary> List<int[, ]> GenerateDetailLayers(TerrainData data, int tileX, int tileZ) { //make sure there are details set if (_detailPrototypes.Length < 1) { return null; } //create all layers //note: each layer is a seperate draw call so try to keep it low var detailLayers = new List<int[,]>(); var detailSize = _terrainSettings.DetailMapSize; var ratio = (float)_terrainSize / (float)detailSize; //create maps for each layer for (int i = 0; i < _detailPrototypes.Length; ++i) { detailLayers.Add(new int[detailSize, detailSize]); } var centerTile = tileX == (_tilesX / 2) && tileZ == (_tilesZ / 2); //fill the layers for (int x = 0; x < detailSize; x++) { for (int z = 0; z < detailSize; z++) { //Set all detail to 0 foreach (var layer in detailLayers) { layer[z, x] = 0; } var unit = 1.0f / (detailSize - 1); var normX = x * unit; var normZ = z * unit; // Get the steepness value at the normalized coordinate. var angle = data.GetSteepness(normX, normZ); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. var frac = angle / 90.0f; //select a random type of layer to use(texture or mesh var rng = Random.value; //Select a random grass layer var grassLayer = Random.Range(0, _grassLayers); //select a random prop layer var propLayer = Random.Range(_grassLayers, _meshLayers + 1); //in the center tile fill it completely with grass, and remove it on locations of props and buildings later if (centerTile) { //prefer to spawn grass if (rng < 0.99f) { detailLayers[grassLayer][z, x] = 1; } else { if (detailLayers.Count > 1) { detailLayers[propLayer][z, x] = 1; } } } else if (frac < 0.5f) { var worldPosX = (x + tileX * (detailSize - 1)) * ratio; var worldPosZ = (z + tileZ * (detailSize - 1)) * ratio; var noise = _detailNoise.FractalNoise2D(worldPosX, worldPosZ, 3, _terrainSettings.DetailFrequency, 1.0f); if (noise > 0.0f) { //prefer to spawn grass if (rng < 0.99f) { detailLayers[grassLayer][z, x] = 1; } else { if (detailLayers.Count > 1) { detailLayers[propLayer][z, x] = 1; } } } } } } return detailLayers; }
/// <summary> /// Generate textures for the terrain /// </summary> float[,,] GenerateAlphaMap(TerrainData data) { //make sure textures have been set if (_splatPrototypes.Length < 1) { return null; } //create map var width = data.alphamapWidth; var height = data.alphamapHeight; var layers = data.alphamapLayers - 1; //ignore the road layer var alphamap = new float[width, height, layers + 1]; for (int x = 0; x < width; ++x) { for (int z = 0; z < height; ++z) { var xNorm = (float)x / (float)width; var zNorm = (float)z / (float)height; //sample height at this location var h = data.GetHeight(z, x); //get normalized coordinates relative to the overall terrain dimensions var normal = data.GetInterpolatedNormal(zNorm, xNorm); //get steepnes at the coordinate var angle = data.GetSteepness(zNorm, xNorm); var weights = new float[layers]; if (layers > 1) { weights[0] = 0.5f; } if (layers > 2) { //more influence at steep heights weights[1] = angle / 90f; } if (layers > 3 && h < 0.4f) { weights[2] = 1f; } float sum = weights.Sum(); //go over all terrain textures for (int i = 1; i < layers; i++) { //normalize weights[i - 1] /= sum; //set weight for correct texture alphamap[x, z, i] = weights[i - 1]; } } } return alphamap; }