Ejemplo n.º 1
0
        void OnEnable()
        {
            Foliage2D foliage = (Foliage2D)target;

            if (foliage.GetComponent <MeshFilter>().sharedMesh == null)
            {
                foliage.RebuildMesh();
            }
        }
Ejemplo n.º 2
0
        static void AddGrassPatch()
        {
            GameObject obj  = new GameObject("New Foliage2D_Object");
            Foliage2D  path = obj.AddComponent <Foliage2D>();

            obj.AddComponent <Foliage2D_Animation>();

            path.SetDefaultMaterial();
            path.RebuildMesh();

            obj.transform.position = GetSpawnPos();

            Selection.activeGameObject = obj;
            EditorGUIUtility.PingObject(obj);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Custom inspector.
        /// </summary>
        private void CustomInspector(Foliage2D foliage2D)
        {
            Undo.RecordObject(target, "Modified Inspector");
            showVisuals = EditorGUILayout.Foldout(showVisuals, "Visual Properties");

            if (showVisuals)
            {
                EditorGUI.indentLevel = 1;
                InspectorBox(10, () =>
                {
                    foliage2D.pixelsPerUnit  = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Pixels To Units", "The number of pixels in 1 Unity unit."), foliage2D.pixelsPerUnit), 1, 768);
                    foliage2D.widthSegments  = Mathf.Clamp(EditorGUILayout.IntField(new GUIContent("With Segments", "The number of columns the mesh has."), foliage2D.widthSegments), 1, 100);
                    foliage2D.heightSegments = Mathf.Clamp(EditorGUILayout.IntField(new GUIContent("Height Segments", "The number of rows the mesh has."), foliage2D.heightSegments), 1, 100);

                    Type utility = Type.GetType("UnityEditorInternal.InternalEditorUtility, UnityEditor");
                    if (utility != null)
                    {
                        PropertyInfo sortingLayerNames = utility.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
                        if (sortingLayerNames != null)
                        {
                            string[] layerNames = sortingLayerNames.GetValue(null, null) as string[];
                            string currName     = foliage2D.GetComponent <Renderer>().sortingLayerName == "" ? "Default" : foliage2D.GetComponent <Renderer>().sortingLayerName;
                            int nameID          = EditorGUILayout.Popup("Sorting Layer", Array.IndexOf(layerNames, currName), layerNames);

                            foliage2D.GetComponent <Renderer>().sortingLayerName = layerNames[nameID];
                        }
                        else
                        {
                            foliage2D.GetComponent <Renderer>().sortingLayerID = EditorGUILayout.IntField("Sorting Layer", foliage2D.GetComponent <Renderer>().sortingLayerID);
                        }
                    }
                    else
                    {
                        foliage2D.GetComponent <Renderer>().sortingLayerID = EditorGUILayout.IntField("Sorting Layer", foliage2D.GetComponent <Renderer>().sortingLayerID);
                    }
                    foliage2D.GetComponent <Renderer>().sortingOrder = EditorGUILayout.IntField("Order in Layer", foliage2D.GetComponent <Renderer>().sortingOrder);
                });
            }
            EditorGUI.indentLevel = 0;

            if (GUILayout.Button("Rebuild Mesh"))
            {
                foliage2D.RebuildMesh();
            }

            if (GUI.changed)
            {
                EditorUtility.SetDirty(target);
                foliage2D.RebuildMesh();
            }

            if (Event.current.type == EventType.ValidateCommand)
            {
                switch (Event.current.commandName)
                {
                case "UndoRedoPerformed":
                    foliage2D.RebuildMesh();
                    break;
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Fills the foliage path with objects.
        /// </summary>
        public void RecreateFoliage()
        {
            foliageCount          = foliageOnPath.Count;
            distanceFromStart     = 0;
            prevDistanceFromStart = 0;
            maxCount = 0;
            float ZAxisOffset = zOffset;

            List <GameObject> foliageP = new List <GameObject>();
            int len = foliagePrefabs.Count;

            foliageP.Clear();
            // The foliage prefabs are placed in a new list to make sure that there are no null fields.
            for (int k = 0; k < len; k++)
            {
                if (foliagePrefabs[k] != null)
                {
                    foliageP.Add(foliagePrefabs[k]);
                }
            }
            maxCount = foliageP.Count;

            // If the prefab list is empty return.
            if (maxCount == 0)
            {
                return;
            }
            objectIndex = 1;

            // Foliage objects are placed on the line described by the path nodes.
            for (int i = 0; i < handlesPosition.Count - 1; i++)
            {
                line       = handlesPosition[i + 1] - handlesPosition[i];
                angleInRad = Mathf.Atan2(line.y, line.x);
                angleInDeg = angleInRad * Mathf.Rad2Deg;
                lineLength = line.magnitude;
                // The vector is normalized so that we can calculate its normal correctly.
                line.Normalize();
                lineNormal            = new Vector2(-line.y, line.x);
                distanceFromStart     = 0;
                prevDistanceFromStart = 0;

                // This loop is executed until the distance between the start of the line and a
                // foliage object is smaller than the length of the line.
                while (true)
                {
                    updatedPrefabIndex = false;

                    // If a new object must be instantiated, updates the "prefabIndex" value.
                    // The value of "prefabIndex" determines which prefab will be instantiated
                    // in the current iteration.
                    if (foliageCount < objectIndex)
                    {
                        if (foliagePattern == Foliage2D_Pattern.Random)
                        {
                            // Get a random index.
                            prefabIndex = Random.Range(0, maxCount);
                        }
                        else
                        {
                            // The value of "prefabIndex" is incremented by 1 so that new objects are instantiated consecutively.
                            prefabIndex++;
                            // If the value of "prefab Index" is bigger than "maxCount" or smaller than 0, we reset it to 0.
                            if (prefabIndex >= maxCount || prefabIndex < 0)
                            {
                                prefabIndex = 0;
                            }
                        }

                        updatedPrefabIndex = true;
                        // We get the Foliage2D component of the prefab with the index of "prefabIndex"
                        // so that we have access to the width of the correct foliage object when we
                        // calculate the distance from the start of the line where this object will be placed.
                        foliage2D = foliageP[prefabIndex].GetComponent <Foliage2D>();
                        DistanceFromStart();
                    }
                    else
                    {
                        foliage2D = foliageOnPath[objectIndex - 1].GetComponent <Foliage2D>();
                        DistanceFromStart();
                    }

                    // If the distance from the start of the line where the last object was placed is
                    // bigger than the line length, the position of the object is reset and the execution
                    // of the while loop is terminated.
                    if (distanceFromStart > lineLength)
                    {
                        foliage2D         = foliageOnPath[prevIndex].GetComponent <Foliage2D>();
                        distanceFromStart = lineLength - foliage2D.width / 2f + lastObjectOffset;

                        if (foliagePathType == Foliage2D_PathType.Smooth)
                        {
                            SmoothPath(i);
                        }
                        else
                        {
                            pointOnTheLine = Vector2.Lerp(handlesPosition[i], handlesPosition[i + 1], distanceFromStart / lineLength);
                        }

                        posOffset = lineNormal * (foliage2D.height / 2f);
                        foliageOnPath[prevIndex].transform.position = transform.TransformPoint(new Vector3(pointOnTheLine.x + posOffset.x, pointOnTheLine.y + posOffset.y, ZAxisOffset));

                        if (updatedPrefabIndex && foliagePattern == Foliage2D_Pattern.Consecutive)
                        {
                            RestorePrefabIndex();
                        }

                        break;
                    }

                    if (foliagePathType == Foliage2D_PathType.Smooth)
                    {
                        SmoothPath(i);
                    }
                    else
                    {
                        pointOnTheLine = Vector2.Lerp(handlesPosition[i], handlesPosition[i + 1], distanceFromStart / lineLength);
                    }

                    if (foliageCount < objectIndex)
                    {
                        // If the index of the current object is bigger than the total number of
                        // instantiated objects, a new object is instantiated.
                        ZAxisOffset *= -1;
                        Vector3 pos = pointOnTheLine + posOffset;
                        pos.z = zOffset;
                        GameObject obj = Instantiate(foliageP[prefabIndex], transform.TransformPoint(pos), Quaternion.Euler(new Vector3(0, 0, angleInDeg))) as GameObject;
                        obj.transform.parent = transform;
                        foliageOnPath.Add(obj);
                        prevIndex    = foliageOnPath.Count - 1;
                        foliageCount = foliageOnPath.Count;
                        Foliage2D objFoliage = obj.GetComponent <Foliage2D>();
                        // The object mesh is recreated so that we don't have 2 objects with the same mesh instance.
                        objFoliage.RebuildMesh();
                        objectIndex++;
                    }
                    else
                    {
                        ZAxisOffset *= -1;
                        prevIndex    = objectIndex - 1;
                        foliageOnPath[objectIndex - 1].transform.position = transform.TransformPoint(new Vector3(pointOnTheLine.x + posOffset.x, pointOnTheLine.y + posOffset.y, ZAxisOffset));
                        foliageOnPath[objectIndex - 1].transform.rotation = Quaternion.Euler(new Vector3(0, 0, angleInDeg));
                        objectIndex++;
                    }
                }
            }

            // If the path shrinked and there is an excess of foliage objects, delete them.
            if (foliageCount + 1 > objectIndex)
            {
                int lenD = foliageCount + 1 - objectIndex;

                for (int i = 0; i < lenD; i++)
                {
                    int last = foliageOnPath.Count - 1;
                    DestroyImmediate(foliageOnPath[last]);
                    foliageOnPath.RemoveAt(last);

                    if (foliagePattern == Foliage2D_Pattern.Consecutive)
                    {
                        RestorePrefabIndex();
                    }
                }
            }
        }