} // 2f; public static RAKBiome getForestBiome() { RAKBiome biome = new RAKBiome(new string[] { RAKUtilities.NON_TERRAIN_OBJECT_HOUSE1, RAKUtilities.NON_TERRAIN_OBJECT_HOUSE2, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_TREE_1, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_TREE_2, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_TREE_3, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_TREE_4, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_BUSH_1, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_BUSH_2, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_BUSH_3, RAKUtilities.NON_TERRAIN_OBJECT_LOW_POLY_BUSH_4, RAKUtilities.NON_TERRAIN_OBJECT_FRUIT_TREE }, new int[] { 5, // House1 5, // House2 0, // Tree01 0, // Tree02 0, // Tree03 0, // Tree04 0, // Bush01 20, // Bush02 20, // Bush03 0, // Bush04 20 // Fruit Tree }); biome.depth = 80; biome.numberOfTrees = 0; biome.offsetX = UnityEngine.Random.Range(0, 100); biome.offsetY = UnityEngine.Random.Range(0, 100); biome.scale = UnityEngine.Random.Range(1, 1.5f); biome.type = BIOMETYPE.Forest; return(biome); }
public void Initialize(World world, HexCell cell) { if (debug) { InitializeDebugTerrain(world, cell); return; } // Set static data // RAKTerrainMaster.world = world; RAKTerrainMaster.cell = cell; DateTime startTime = DateTime.Now; terrain = new RAKTerrain[worldSize]; // Check if files are already present for this cell // bool saveDataAvail = IsSaveDataAvailable(cell, world.WorldName); if (forceGenerate) { saveDataAvail = false; } if (cell.GetChunkMaterial() == HexGridChunk.ChunkMaterial.GRASS) { currentBiome = RAKBiome.getForestBiome(); } else { currentBiome = RAKBiome.getForestBiome(); } #region TERRAIN GENERATION // Load single terrain loop // for (int count = 0; count < worldSize; count++) { TerrainData td; RAKTerrainSavedData savedTerrain = null; // If no save data available, go ahead and generate a new terrain // if (!saveDataAvail) // generate // { TerrainData previousTD = null; if (count > 0) { currentBiome.GetNewOffsets(); } td = generateTerrain(width, height, currentBiome.depth, currentBiome.scale, currentBiome.offsetX, currentBiome.offsetY); generateSplatPrototypes(td); } // Save data is available // else { savedTerrain = RAKTerrainSavedData.loadTerrain(cell.GetCellSaveFileName(world.WorldName) + "T" + count + ".area"); td = savedTerrain.generateTerrainDataFromFlatMap(); Debug.LogWarning("Loading terrain from disk tdsize - " + td.size.x + "-" + td.size.y + "-" + td.size.z); } // TerrainData generation complete, finish setting up Unity objects // GameObject go = Terrain.CreateTerrainGameObject(td); go.isStatic = false; go.transform.SetParent(transform); go.name = "Terrain" + count; logDebug("Terrain created - " + go.name); Terrain terrainComp = go.GetComponent <Terrain>(); terrain[count] = go.AddComponent <RAKTerrain>(); terrain[count].initialize(this); terrain[count].savedData = savedTerrain; mapPositions(count); terrain[count].setBiome(RAKBiome.getForestBiome()); } // Tell Unity which terrain objects are next to each other // setNeighbors(); // If we are generating new world terrains, fix the sides and seam together // if (!saveDataAvail) { fixGaps(16); } // Generate the terrain details // for (int count = 0; count < terrain.Length; count++) { generateSplatMap(terrain[count].getTerrainData()); // If no save data, generate new details // if (!saveDataAvail) { generateNonTerrainDetailPrefabs(terrain[count].getTerrainComponenet()); } // Save data avail, load details from disk // else { Debug.Log("Loading terrain from disk"); generateNonTerrainDetailsFromDisk(terrain[count]); } } #endregion float currentTime = Time.time; /*List<NavMeshSurface> surfaces = new List<NavMeshSurface>(); * surfaces.Add(gameObject.AddComponent<NavMeshSurface>()); * surfaces[0].collectObjects = CollectObjects.Children; * RAKMeshBaker.Bake(surfaces.ToArray()); * Debug.LogWarning("Build nav mesh took - " + (Time.time - currentTime));*/ // Save to disk if needed // if (!saveDataAvail) { SaveTerrainData(); } // Finish loading // RAKTerrainMaster.generateCreatures(cell, world); RAKTerrainMaster.sun = gameObject.AddComponent <RAKWeather>(); RAKTerrainMaster.sun.start(transform, this, sun.gameObject); TimeSpan difference = startTime.Subtract(DateTime.Now); Debug.LogWarning("LOAD TIME - " + difference.TotalMilliseconds); }
// Generate details for a RAKTerrain object // private void generateNonTerrainDetailPrefabs(Terrain terrain) { RAKTerrain rakTerrain = terrain.GetComponent <RAKTerrain>(); TerrainData data = terrain.terrainData; RAKBiome biome = rakTerrain.getBiome(); int sum = 0; Array.ForEach(biome.objectCounts, delegate(int i) { sum += i; }); int totalNumberOfObjects = sum; GameObject[] details = new GameObject[totalNumberOfObjects]; int currentDetailCount = 0; for (int currentObjectCount = 0; currentObjectCount < biome.objectCounts.Length; currentObjectCount++) { GameObject prefab = null; try { prefab = RAKUtilities.getTerrainObjectPrefab(biome.prefabNames[currentObjectCount]); } catch (Exception e) { Debug.LogWarning("Unable to get prefab - " + biome.prefabNames[currentObjectCount]); continue; } RAKTerrainObject terrainObject = prefab.GetComponent <RAKTerrainObject>(); terrainObject.UpdatePropertiesBasedOnName(prefab.name); int maxTries = terrainObject.numberOfTimesToSearchForLocation; float maxSteepness = terrainObject.maxSteepness; float minDistFromEdge = terrainObject.minDistFromEdge; float minimiumDistanceBetweenObjects = terrainObject.minimiumDistanceBetweenObjects; float heightOffset = terrainObject.heightOffset; MeshFilter meshFilter = terrainObject.GetComponent <MeshFilter>(); float detailHeight, detailWidthX, detailWidthZ; if (meshFilter == null) { detailHeight = 1; detailWidthX = 1; detailWidthZ = 1; } else { detailHeight = prefab.GetComponent <MeshFilter>().sharedMesh.bounds.size.y *prefab.transform.localScale.y; detailWidthX = prefab.GetComponent <MeshFilter>().sharedMesh.bounds.size.x *prefab.transform.localScale.x; detailWidthZ = prefab.GetComponent <MeshFilter>().sharedMesh.bounds.size.z *prefab.transform.localScale.z; } // Sometimes we need to force a width if the bottom of the object is skinny (trees) // if (terrainObject.sizeOverride != Vector3.zero) { detailWidthX = terrainObject.sizeOverride.x; detailWidthZ = terrainObject.sizeOverride.z; detailHeight = terrainObject.sizeOverride.y; } float widthXNorm = (detailWidthX / data.heightmapWidth) * 100; float widthZNorm = (detailWidthZ / data.heightmapHeight) * 100; string debugString = ""; for (int count = 0; count < biome.objectCounts[currentObjectCount]; count++) { bool locationValid = false; float x = 0; float z = 0; float y = 0; int tries = 0; while (!locationValid) { locationValid = true; tries++; x = UnityEngine.Random.Range(0, width); z = UnityEngine.Random.Range(0, height); float zNormed = (float)z / (float)data.heightmapHeight; float xNormed = (float)x / (float)data.heightmapWidth; y = data.GetInterpolatedHeight(xNormed, zNormed) - detailHeight - heightOffset; if (x < detailWidthX + minDistFromEdge || x > width - detailWidthX - minDistFromEdge) { locationValid = false; debugString = "Too close to edgeX - " + x; continue; } if (z < detailWidthZ + minDistFromEdge || z > height - detailWidthZ - minDistFromEdge) { locationValid = false; debugString = "Too close to edgeZ - " + z; continue; } locationValid = true; for (int otherObjectsCount = 0; otherObjectsCount < details.Length; otherObjectsCount++) { if (details[otherObjectsCount] != null) { if (Vector2.Distance(new Vector2(terrain.transform.position.x + x, terrain.transform.position.z + z), new Vector2(details[otherObjectsCount].transform.position.x, details[otherObjectsCount].transform.position.z)) < details[otherObjectsCount].GetComponent <RAKTerrainObject>().minimiumDistanceBetweenObjects) { locationValid = false; debugString = "Too close to other object - " + (Vector2.Distance(new Vector2(terrain.transform.position.x + x, terrain.transform.position.z + z), new Vector2(details[otherObjectsCount].transform.position.x, details[otherObjectsCount].transform.position.z)) + " - " + (details[otherObjectsCount].GetComponent <RAKTerrainObject>().minimiumDistanceBetweenObjects)); break; } } } if (locationValid) { for (int countX = (int)-widthXNorm; countX < widthXNorm; countX++) { for (int countZ = (int)-widthZNorm; countZ < widthZNorm; countZ++) { float steepness = data.GetSteepness((x + countX) / data.alphamapWidth, (z + countZ) / data.alphamapHeight); if (steepness > maxSteepness) { locationValid = false; debugString = "Too steep - " + steepness + " - " + maxSteepness; } } } } if (tries >= maxTries) { Debug.LogWarning(debugString + " - " + terrainObject.name); break; } } if (locationValid) { details[currentDetailCount] = (GameObject)Instantiate(prefab, new Vector3 (x + terrain.transform.position.x, y + detailHeight, z + terrain.transform.position.z), Quaternion.identity);//, 3); details[currentDetailCount].gameObject.name = prefab.name; details[currentDetailCount].transform.SetParent(terrain.transform); Debug.LogWarning("Instantiated - " + details[currentDetailCount].name); //details[currentDetailCount].GetComponent<RAKTerrainObject>().setPrefabObjectName(prefab.name); //details[currentDetailCount].transform.position = new Vector3(x + terrain.transform.position.x, y + detailHeight, z + terrain.transform.position.z); if (!terrainObject.freeRotate) { details[currentDetailCount].transform.rotation = Quaternion.Euler(new Vector3(0, UnityEngine.Random.Range(0, 360), 0)); } else { details[currentDetailCount].transform.rotation = Quaternion.Euler(new Vector3(UnityEngine.Random.Range(0, 360), UnityEngine.Random.Range(0, 360), UnityEngine.Random.Range(0, 360))); } } currentDetailCount++; } } if (details != null) { List <RAKTerrainObject> nonTerrainObjects = new List <RAKTerrainObject>(); for (int count = 0; count < details.Length; count++) { if (details[count] != null) { RAKTerrainObject terrainObject = details[count].GetComponent <RAKTerrainObject>(); nonTerrainObjects.Add(terrainObject); } } rakTerrain.nonTerrainObjects = nonTerrainObjects.ToArray(); } }