// Method creates meshes of all objects per biome List <BiomeMesh> BuildMeshes() { // Create a new list of all meshes on the terrain List <BiomeMesh> biomeMeshes = new List <BiomeMesh>(); // Loop through all biomes for (int i = 0; i < biomes.Length; i++) { // For each new biome, add a new 2 dimensional list of gameobjects (for each terrainobject their exists a list of gameobject holding meshes of that object) worldObjects.Add(new List <List <GameObject> >()); // Create a new biomemesh which holds the meshes and other details for the current biome BiomeMesh biomeMesh = new BiomeMesh(); // Loop through each of the objects added to the biome for (int j = 0; j < biomes[i].biomeObjects.Length; j++) { // Get all parameters that were set on that specific terrain object GameObject obj = biomes[i].biomeObjects[j].prefab; float occurance = biomes[i].biomeObjects[j].occurance; float minScale = biomes[i].biomeObjects[j].minScale; float maxScale = biomes[i].biomeObjects[j].maxScale; float minRot = biomes[i].biomeObjects[j].minRotation; float maxRot = biomes[i].biomeObjects[j].maxRotation; Mesh[] subMeshes = GetSubmeshes(obj); // Add a mesh to the current biome adding also its details biomeMesh.AddMesh(GetSubmeshes(obj), occurance, objectPerTile, minScale, maxScale, minRot, maxRot); // Add to the worldObjects list a new list of GameObjects that holds on the first place the prefab mesh. (Is used to instantiate new ones from) worldObjects[i].Add(new List <GameObject>()); biomes[i].biomeObjects[j].emptyPrefab.GetComponent <TerrainObject>().numVerticesPerObject = new List <int>(); for (int k = 0; k < subMeshes.Length; k++) { biomes[i].biomeObjects[j].emptyPrefab.GetComponent <TerrainObject>().numVerticesPerObject.Add(subMeshes[k].vertexCount); } worldObjects[i][j].Add(biomes[i].biomeObjects[j].emptyPrefab); } // Add the biomeMesh to the list of all biomeMeshes biomeMeshes.Add(biomeMesh); } return(biomeMeshes); }
// Method that generates each of the Objects on the terrain IEnumerator GenerateBiomeAttributes() { // Index to keep track of how much time it takes float timeSinceUpdate = Time.realtimeSinceStartup; // Loop through each grid tile in the world for (int i = 0; i < chunks.Count; i++) { for (int k = 0; k < chunks[i].tiles.Count; k++) { GridTile tile = chunks[i].tiles[k]; // If the grid tile is under the water level, don't do anything. if (tile == null) { continue; } if (tile.position.y < waterLevel) { continue; } // Get all Meshes with parameters of the biome BiomeMesh curBiomeMesh = biomeMeshes[Mathf.FloorToInt(tile.biome)]; List <float> occurances = curBiomeMesh.occurance; int objectsPerTile = curBiomeMesh.objectsPerTile * tileSize / 20; if (objectsPerTile < 1) { objectPerTile = 1; } List <float> minScale = curBiomeMesh.minScale; List <float> maxScale = curBiomeMesh.maxScale; List <float> minRot = curBiomeMesh.minRot; List <float> maxRot = curBiomeMesh.maxRot; for (int l = 0; l < objectsPerTile; l++) { // create a random variable between 0 and 1 float choice = (float)rand.NextDouble(); // Create a lower and upper limit float lower = 0; float upper = 0; for (int j = 0; j < occurances.Count; j++) { // Add the occurance of the current object to the upper limit upper += occurances[j]; // If the random variable is between upper and lower limit generate that object if (choice < upper * tileSize / 20 && choice > lower * tileSize / 20) { // Determine a random scale and rotation, based on the min and max set by the user float scale = minScale[j] + (float)rand.NextDouble() * (maxScale[j] - minScale[j]); float rot = minRot[j] + (float)rand.NextDouble() * (maxRot[j] - minRot[j]); Vector3 pos = tile.position + Vector3.right * tileSize * ((float)rand.NextDouble() - 0.5f) + Vector3.forward * tileSize * ((float)rand.NextDouble() - 0.5f); // Generate the object GenerateObject(pos, Quaternion.Euler(0, rot, 0), Vector3.one * scale, Mathf.FloorToInt(tile.biome), j, tile, chunks[i]); // Break the loop for this grid tile break; } // Set the current upper to the lower limit lower = upper; } } // index is bigger than the set value wait for one frame update if (Time.realtimeSinceStartup - timeSinceUpdate > 1f / 10) { yield return(null); timeSinceUpdate = Time.realtimeSinceStartup; } } for (int biome = 0; biome < biomes.Length; biome++) { for (int objs = 0; objs < worldObjects[biome].Count; objs++) { List <GameObject> curGameObjectList = worldObjects[biome][objs]; if (curGameObjectList.Count < 2 && !curGameObjectList[curGameObjectList.Count - 1].GetComponent <TerrainObject>().hasReloaded) { continue; } curGameObjectList[curGameObjectList.Count - 1].GetComponent <TerrainObject>().verticesNow = 65001; } } } // When done, be sure the check if all meshes have been updated BuildMeshesAll(); }