/// <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);
        }
    }