// ----------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------- public virtual bool ValidateTerrainType(HeightTemplate heightType, TemperatureTemplate heatType, MoistureTemplate moistureType, DifficultyTemplate difficultyType, BiomeTemplate biomeType = null) { bool bValid = (Random.value <= chance); // -- validate height (if any) if (heightType != null && heightTypes != null && heightTypes.Length > 0) { bValid = (heightTypes.Any(x => x.name == heightType.name)) ? bValid : false; } // -- validate heat (if any) if (heatType != null && heatTypes != null && heatTypes.Length > 0) { bValid = (heatTypes.Any(x => x.name == heatType.name)) ? bValid : false; } // -- validate moisture (if any) if (moistureType != null && moistureTypes != null && moistureTypes.Length > 0) { bValid = (moistureTypes.Any(x => x.name == moistureType.name)) ? bValid : false; } // -- validate difficulty (if any) if (difficultyType != null && difficultyTypes != null && difficultyTypes.Length > 0) { bValid = (difficultyTypes.Any(x => x.name == difficultyType.name)) ? bValid : false; } return(bValid); }
// ----------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------- private Texture2D BuildBiomeTexture(HeightTemplate[,] heightTypes, TemperatureTemplate[,] heatTypes, MoistureTemplate[,] moistureTypes, DifficultyTemplate[,] difficultyTypes, BiomeTemplate[,] chosenBiomes) { int tileSize = heatTypes.GetLength(0); Color[] colorMap = new Color[tileSize * tileSize]; for (int zIndex = 0; zIndex < tileSize; zIndex++) { for (int xIndex = 0; xIndex < tileSize; xIndex++) { int colorIndex = zIndex * tileSize + xIndex; HeightTemplate heightType = heightTypes [zIndex, xIndex]; // check if the current coordinate is a water region //if (heightTerrainType.name != "water") { // a coordinates biome will be defined by the heat and moisture values TemperatureTemplate heatType = heatTypes [zIndex, xIndex]; MoistureTemplate moistureType = moistureTypes [zIndex, xIndex]; DifficultyTemplate difficultyType = difficultyTypes [zIndex, xIndex]; // choose biome template (if any) System.Random rnd = new System.Random(); List <BiomeTemplate> finalBiomes = new List <BiomeTemplate>(); foreach (BiomeTemplate tmpl in root.biomeSettings.templates) { if (tmpl.ValidateTerrainType(heightType, heatType, moistureType, difficultyType)) { finalBiomes.Add(tmpl); } } BiomeTemplate biome = finalBiomes[rnd.Next(finalBiomes.Count)]; // assign the color according to the selected biome colorMap [colorIndex] = biome.color; // save biome in chosenBiomes matrix only when it is not water chosenBiomes [zIndex, xIndex] = biome; //} else { // water regions don't have biomes, they always have the same color // colorMap [colorIndex] = this.waterColor; //} } } // create a new texture and set its pixel colors Texture2D tileTexture = new Texture2D(tileSize, tileSize); tileTexture.wrapMode = TextureWrapMode.Clamp; tileTexture.SetPixels(colorMap); tileTexture.Apply(); return(tileTexture); }
// ----------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------- public override bool ValidateTerrainType(HeightTemplate heightType, TemperatureTemplate heatType, MoistureTemplate moistureType, DifficultyTemplate difficultyType, BiomeTemplate biomeType = null) { bool bValid = base.ValidateTerrainType(heightType, heatType, moistureType, difficultyType); // -- validate biome (if any) if (biomeType != null && biomeTypes.Length > 0) { bValid = (biomeTypes.Any(x => x.name == biomeType.name)) ? bValid : false; } return(bValid); }
// ----------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------- public TileData GenerateTile(LevelGeneration _levelGeneration) { // setup dependencies root = _levelGeneration; noiseMapGeneration.root = root; // calculate tile depth and width based on the mesh vertices meshVertices = meshFilter.sharedMesh.vertices; tileSize = (int)Mathf.Sqrt(meshVertices.Length); // calculate the offsets based on the tile position offsetX = -this.gameObject.transform.position.x; offsetZ = -this.gameObject.transform.position.z; // calculate vertex offset based on the Tile position and the distance between vertices Vector3 tileDimensions = meshFilter.sharedMesh.bounds.size; float distanceBetweenVertices = tileDimensions.z / (float)tileSize; vertexOffset = this.gameObject.transform.position.z / distanceBetweenVertices; GenerateHeightMap(); GenerateHeatMap(); GenerateMoistureMap(); GenerateDifficultyMap(); // ------- build all textures --------- // build a Texture2D from the height map HeightTemplate[,] chosenHeightTypes = new HeightTemplate[tileSize, tileSize]; heightTexture = BuildTexture(heightMap, root.heightSettings.templates, chosenHeightTypes); // build a Texture2D from the heat map TemperatureTemplate[,] chosenHeatTypes = new TemperatureTemplate[tileSize, tileSize]; heatTexture = BuildTexture(heatMap, root.temperatureSettings.templates, chosenHeatTypes); // build a Texture2D from the moisture map MoistureTemplate[,] chosenMoistureTypes = new MoistureTemplate[tileSize, tileSize]; moistureTexture = BuildTexture(moistureMap, root.moistureSettings.templates, chosenMoistureTypes); // build a Texture2D from the difficulty map DifficultyTemplate[,] chosenDifficultyTypes = new DifficultyTemplate[tileSize, tileSize]; difficultyTexture = BuildTexture(difficultyMap, root.difficultySettings.templates, chosenDifficultyTypes); // build a biomes Texture2D from the three other noise variables BiomeTemplate[,] chosenBiomes = new BiomeTemplate[tileSize, tileSize]; biomeTexture = BuildBiomeTexture(chosenHeightTypes, chosenHeatTypes, chosenMoistureTypes, chosenDifficultyTypes, chosenBiomes); // ------- // update the visualization mode UpdateVisualizationMode(); // update the tile mesh vertices according to the height map UpdateMeshVertices(heightMap); TileData tileData = new TileData(heightMap, heatMap, moistureMap, difficultyMap, chosenHeightTypes, chosenHeatTypes, chosenMoistureTypes, chosenDifficultyTypes, chosenBiomes, meshFilter.mesh, (Texture2D)this.tileRenderer.sharedMaterial.mainTexture); return(tileData); }
// ----------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------- public void Generate(int mapSize, float _distanceBetweenVertices, LevelData levelData) { if (!active) { return; } distanceBetweenVertices = _distanceBetweenVertices; for (int i = 0; i < doodads.Length; i++) { // generate a root object root = new GameObject("DoodadRoot_" + i.ToString()); root.transform.parent = this.gameObject.transform; // select doodads to generate DoodadRow chosenDoodads = doodads[i]; // generate a tree noise map using Perlin Noise float[,] treeMap = this.noiseMapGeneration.GeneratePerlinNoiseMap(mapSize, levelData.scale, 0, 0, this.waves); //float levelSizeX = mapSize * distanceBetweenVertices; for (int zIndex = 0; zIndex < mapSize; zIndex++) { for (int xIndex = 0; xIndex < mapSize; xIndex++) { // convert from Level Coordinate System to Tile Coordinate System and retrieve the corresponding TileData TileCoordinate tileCoordinate = levelData.ConvertToTileCoordinate(zIndex, xIndex); TileData tileData = levelData.tilesData [tileCoordinate.tileZIndex, tileCoordinate.tileXIndex]; int tileWidth = tileData.heightMap.GetLength(1); // calculate the mesh vertex index meshVertices = tileData.mesh.vertices; int vertexIndex = tileCoordinate.coordinateZIndex * tileWidth + tileCoordinate.coordinateXIndex; // sample all map data at this coordinate HeightTemplate heightType = tileData.chosenHeightTypes [tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex]; TemperatureTemplate heatType = tileData.chosenHeatTypes [tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex]; MoistureTemplate moistureType = tileData.chosenMoistureTypes [tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex]; DifficultyTemplate difficultyType = tileData.chosenDifficultyTypes [tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex]; BiomeTemplate biomeType = tileData.chosenBiomes [tileCoordinate.coordinateZIndex, tileCoordinate.coordinateXIndex]; // choose doodad template (if any) DoodadTemplate template = null; System.Random rnd = new System.Random(); List <DoodadTemplate> finalDoodads = new List <DoodadTemplate>(); foreach (DoodadTemplate tmpl in chosenDoodads.doodads) { if (tmpl.ValidateTerrainType(heightType, heatType, moistureType, difficultyType, biomeType)) { finalDoodads.Add(tmpl); } } if (finalDoodads.Count > 0) { template = finalDoodads[rnd.Next(finalDoodads.Count)]; } // validate doodad if (template != null) { float treeValue = treeMap [zIndex, xIndex]; //int terrainTypeIndex = terrainType.index; // compares the current tree noise value to the neighbor ones int neighborZBegin = (int)Mathf.Max(0, zIndex - template.neighborRadius * levelGeneration.scaleMultiplier); int neighborZEnd = (int)Mathf.Min(mapSize - 1, zIndex + template.neighborRadius * levelGeneration.scaleMultiplier); int neighborXBegin = (int)Mathf.Max(0, xIndex - template.neighborRadius * levelGeneration.scaleMultiplier); int neighborXEnd = (int)Mathf.Min(mapSize - 1, xIndex + template.neighborRadius * levelGeneration.scaleMultiplier); float maxValue = 0f; for (int neighborZ = neighborZBegin; neighborZ <= neighborZEnd; neighborZ++) { for (int neighborX = neighborXBegin; neighborX <= neighborXEnd; neighborX++) { float neighborValue = treeMap [neighborZ, neighborX]; // saves the maximum tree noise value in the radius if (neighborValue >= maxValue) { maxValue = neighborValue; } } } // if the current tree noise value is the maximum one, place a tree in this location if (treeValue == maxValue) { InstantiateDoodad(template, zIndex, xIndex, vertexIndex); } } } } } }