/// <summary> /// Generates one plant by randomizing its variables and spawning it on terrainchunks /// </summary> /// <param name="spawnSettings"></param> /// <returns></returns> private GameObject generateNewPlant(PlantSpawnSettings spawnSettings) { StartCoroutine(randomizeHoudiniVars(spawnSettings)); GameObject newPlant = new GameObject("Plant"); // TODO: change name newPlant.transform.localScale = spawnSettings.mainHoudiniPlant.transform.localScale; //I = 1 because we skip the HDA_Data GameObject for (int i = 1; i < spawnSettings.mainHoudiniPlant.transform.childCount; i++) { GameObject plantPart = Instantiate(spawnSettings.mainHoudiniPlant.transform.GetChild(i).gameObject); plantPart.transform.SetParent(newPlant.transform); plantPart.transform.localScale = spawnSettings.mainHoudiniPlant.transform.GetChild(i).localScale; } return(newPlant); }
/// <summary> /// Randomizes the houdini variables of one plant according to the randomizer settings /// </summary> /// <param name="spawnSettings"></param> /// <returns></returns> private IEnumerator randomizeHoudiniVars(PlantSpawnSettings spawnSettings) { HEU_HoudiniAssetRoot assetRoot = spawnSettings.mainHoudiniPlant.GetComponent <HEU_HoudiniAssetRoot>(); foreach (PlantVariationSetting variation in spawnSettings.randomizers) { switch (variation.type) { case PlantVariationTypes.Int: HEU_ParameterUtility.SetInt(assetRoot._houdiniAsset, variation.houdiniKey, Random.Range((int)variation.minValue, (int)variation.maxValue)); break; case PlantVariationTypes.Float: HEU_ParameterUtility.SetFloat(assetRoot._houdiniAsset, variation.houdiniKey, Random.Range(variation.minValue, variation.maxValue)); break; } } assetRoot._houdiniAsset.RequestCook(bCheckParametersChanged: true, bAsync: false, bSkipCookCheck: true, bUploadParameters: true); yield return(null); }
/// <summary> /// Spawns the required amount of plants on the current chunk /// </summary> /// <param name="chunk"></param> /// <param name="plantSpawnSettings"></param> /// <param name="amountOfPlants"></param> /// <param name="chunks"></param> /// <returns></returns> public IEnumerator SpawnPlantsOnChunk(TerrainChunk chunk, List <PlantSpawnSettings> plantSpawnSettings, int amountOfPlants, List <TerrainChunk> chunks) { for (int i = 0; i < amountOfPlants; i++) { int randomPlantIndex = Random.Range(0, plantSpawnSettings.Count); PlantSpawnSettings spawnSettings = plantSpawnSettings[randomPlantIndex]; AbstractPlacementStrategy placementStrategy; if (spawnSettings.placementStrategy.GetClass().IsSubclassOf(typeof(AbstractPlacementStrategy))) { placementStrategy = Activator.CreateInstance(spawnSettings.placementStrategy.GetClass()) as AbstractPlacementStrategy; } else { throw new Exception($"[PlantGenerator] The Random Placement script on plant #{randomPlantIndex} does not extend from AbstractPlacementStrategy!"); } float chunkX = chunk.chunkObject.transform.position.x; float chunkZ = chunk.chunkObject.transform.position.z; float chunkSizeXHalf = chunk.size.x / 2; float chunkSizeZHalf = chunk.size.y / 2; Vector3 position = placementStrategy.RandomizePosition(this, chunk, chunkX - chunkSizeXHalf, chunkX + chunkSizeXHalf, chunkZ - chunkSizeZHalf, chunkZ + chunkSizeZHalf); if (spawnSettings.mainHoudiniPlant == null) { Debug.LogError("Error creating plant: No main houdini plant found"); yield break; } GameObject newPlant = generateNewPlant(spawnSettings); newPlant.transform.SetParent(chunk.chunkObject.transform); newPlant.transform.position = position; newPlant.isStatic = true; currentPlant++; float percentageDone = (float)currentPlant / (float)amountOfPlantsToSpawn; eta.Update(percentageDone); string extraText = ""; if (eta.ETAIsAvailable) { extraText += $"Estimated time left: {eta.ETR.Hours}:{eta.ETR.Minutes}:{eta.ETR.Seconds}"; } cancel = EditorUtility.DisplayCancelableProgressBar("Busy generating plants...", $"Generating plants {currentPlant} / {amountOfPlantsToSpawn} {extraText}", percentageDone); if (cancel) { StopAllCoroutines(); generatingPlants = false; Transform plantsHolder = transform.Find("Plants"); plantsHolder.gameObject.SetActive(true); EditorUtility.ClearProgressBar(); //Turning chunks back on foreach (TerrainChunk terrainChunk in chunks) { terrainChunk.SetActive(true); } } yield return(newPlant); } }