/// <summary>
        /// Used to draw the inspector GUI for the plant generator object.
        /// </summary>
        public override void OnInspectorGUI()
        {
            PlantDefinition plantDefinition = target as PlantDefinition;

            int minBranchCount;
            int maxBranchCount;

            plantDefinition.GetMinMaxBranchCount(out minBranchCount, out maxBranchCount);

            GUILayout.Label("Total Branches: " + minBranchCount + " - " + maxBranchCount);
            EditorGUILayout.Separator();

            using (new GUILayout.HorizontalScope())
            {
                GUILayout.Label("NAME", GUILayout.Width(100));
                GUILayout.Label("COUNT", GUILayout.Width(60));
                GUILayout.Label("%", GUILayout.Width(50));
            }

            for (int i = 0; i < plantDefinition.GroupParameters.Length; i++)
            {
                PlantDefinition.BranchGroupParameters branchParameters = plantDefinition.GroupParameters[i];

                using (new GUILayout.HorizontalScope())
                {
                    branchParameters.Name = GUILayout.TextField(branchParameters.Name ?? "", GUILayout.Width(100));

                    branchParameters.MinCount = this.IntegerTextField(branchParameters.MinCount);
                    GUILayout.Label("-", GUILayout.Width(7));
                    branchParameters.MaxCount = this.IntegerTextField(branchParameters.MaxCount);

                    int minPercent = Mathf.RoundToInt(100 * ((float)branchParameters.MinCount) / ((float)maxBranchCount));
                    int maxPercent = Mathf.RoundToInt(100 * ((float)branchParameters.MaxCount) / ((float)minBranchCount));
                    GUILayout.Label(minPercent + "% - " + maxPercent + "%", GUILayout.Width(50));
                }
            }

            EditorGUILayout.Separator();

            base.OnInspectorGUI();
        }
        /// <summary>
        /// Uses the the plant parameters to generates a new plant.
        /// </summary>
        private void Generate()
        {
            // making sure it hasn't already been generated
            if (this.isGenerated)
            {
                return;
            }

            // making sure layerId gets initialized
            if (layerId == -1)
            {
                layerId = LayerMask.NameToLayer(PlantDefinition.LayerName);

                if (layerId == -1)
                {
                    string message = string.Format("PlantGenerator couldn't find layer \"{0}\".  To stop the plants from jiggling, go to the menu \"Edit -> Project Settings -> Tags and Layers\" and make sure the layer \"{0}\" exists.", PlantDefinition.LayerName);
                    Debug.LogError(message, this.gameObject);
                }
                else
                {
                    Physics.IgnoreLayerCollision(layerId, layerId);
                }
            }

            System.Random          rand = new System.Random(this.seed);
            SuitableRotationSystem suitableRotationSystem = new SuitableRotationSystem(rand);

            if (this.plantDefinition.GroupParameters.Length == 0)
            {
                Debug.LogError("Plant doesn't have any Group Parameters specified", this.gameObject);
                return;
            }

            for (int i = 0; i < this.plantDefinition.GroupParameters.Length; i++)
            {
                PlantDefinition.BranchGroupParameters groupParameters = this.plantDefinition.GroupParameters[i];

                if (groupParameters.MinCount < 0 || groupParameters.MaxCount < 0)
                {
                    Debug.LogError("Plant has invalid Min/Max count.  Min and Max must be greater than or equal to 0", this.gameObject);
                    return;
                }

                if (groupParameters.MinCount > groupParameters.MaxCount)
                {
                    Debug.LogError("Plant has invalid Min/Max count.  Min must be less than or equal to Max", this.gameObject);
                    return;
                }

                if (groupParameters.MinCount == 0 && groupParameters.MaxCount == 0)
                {
                    Debug.LogError("Plant have Min/Max both equal to 0.  That group will never be created.", this.gameObject);
                    return;
                }

                int branchTypeCount = Mathf.RoundToInt(RandomUtil.IntRangeInclusive(rand, groupParameters.MinCount, groupParameters.MaxCount));

                for (int j = 0; j < branchTypeCount; j++)
                {
                    if (groupParameters.Variations == null || groupParameters.Variations.Length == 0)
                    {
                        Debug.LogError("Plant has invalid number of Variations.  Must have at least 1.", this.gameObject);
                        return;
                    }

                    // creating the new branch
                    int        variationIndex = rand.Next(groupParameters.Variations.Length);
                    GameObject prototypePlant = groupParameters.Variations[variationIndex];

                    if (prototypePlant == null)
                    {
                        Debug.LogError(string.Format("Plant has null GameObject in Variation Element {0}.", variationIndex), this.gameObject);
                        return;
                    }

                    GameObject newBranch = Pooler.Instantiate(prototypePlant);

                    // setting up the base rotation
                    float baseRotation = 360 * ((float)j / (float)branchTypeCount);
                    baseRotation = suitableRotationSystem.GetSuitibleRotation(baseRotation);
                    suitableRotationSystem.AddDeadSpot(baseRotation, groupParameters.RotationalWidth);

                    // generating height offset
                    float height = RandomUtil.FloatRangeExclusive(rand, -groupParameters.VerticalOffset, groupParameters.VerticalOffset);

                    // setting the new plants transform values
                    newBranch.transform.parent           = this.transform;
                    newBranch.transform.localPosition    = new Vector3(0, height, 0);
                    newBranch.transform.localEulerAngles = new Vector3(0, baseRotation, 0);
                    newBranch.transform.localScale       = Vector3.one;

                    // setting the layer
                    if (layerId != -1)
                    {
                        newBranch.layer = layerId;
                    }

                    // setting the branch rotation (off of the base)
                    PlantGeneratorBranch plantBranch = newBranch.GetComponent <PlantGeneratorBranch>();
                    float addedRotation = RandomUtil.FloatRangeExclusive(rand, groupParameters.RandomRotationOffset, -groupParameters.RandomRotationOffset);
                    plantBranch.transform.localEulerAngles += new Vector3(0, addedRotation, 0);

                    // setting a random material on all renderers of this branch
                    if (groupParameters.Materials != null && groupParameters.Materials.Length > 0)
                    {
                        int      index       = rand.Next(groupParameters.Materials.Length);
                        Material newMaterial = groupParameters.Materials[index];

                        if (newMaterial != null)
                        {
                            var renderers = plantBranch.GetComponentsInChildren <Renderer>();

                            for (int r = 0; r < renderers.Length; r++)
                            {
                                renderers[r].sharedMaterial = newMaterial;
                            }
                        }
                    }
                }

                // if we got here then everything generated properly
                this.isGenerated     = true;
                this.destroyChildren = true;
            }
        }