Example #1
0
        /// <summary>
        /// Add a new prefab to the spline
        /// </summary>
        // TODO: rewrite, use different approach: Use fake splines around the current spline. That way the separation distance doesn't matter
        //       and you could have small prefabs on the outer spline, and big prefabs on the inner spline and they would distribute better
        private GameObject AddPrefab(ref int prefabInstanceIndex, Vector3 position, Vector3 direction, List <SplinePoint> splinePoints, int currentSplinePointIndex)
        {
            GameObject instance = null;

            // offset for lanes: lanes are from left to right, center is the spline.
            // so a spline with 5 lanes has these offset lanes: -2, -1, 0, 1, 2
            int offsetLane = -prefabPainter.splineSettings.lanes / 2;

            for (var lane = 1; lane <= prefabPainter.splineSettings.lanes; lane++)
            {
                // skip center lane if requestred
                if (prefabPainter.splineSettings.skipCenterLane && offsetLane == 0)
                {
                    offsetLane++;
                    continue;
                }

                // get settings for the prefab to instantiate
                PrefabSettings prefabSettings = prefabPainter.GetPrefabSettings();

                // check if we have settings at all
                if (prefabSettings == null)
                {
                    return(null);
                }

                // instance will be created or used => advance index
                prefabInstanceIndex++;

                // check if we have to create a new instance or use an existing one
                if (prefabPainter.splineSettings.reusePrefabs)
                {
                    if (prefabInstanceIndex < prefabPainter.splineSettings.prefabInstances.Count)
                    {
                        instance = prefabPainter.splineSettings.prefabInstances[prefabInstanceIndex];
                    }
                }

                // create instance if we don't have one yet
                if (instance == null)
                {
                    instance = GameObject.Instantiate(prefabSettings.prefab);

                    prefabPainter.splineSettings.prefabInstances.Add(instance);
                }

                // reset position & rotation
                instance.transform.position = position;
                instance.transform.rotation = Quaternion.identity;

                ApplyPrefabSettings(offsetLane, prefabSettings, instance, position, direction, splinePoints, currentSplinePointIndex);

                // reparent the child to the container
                instance.transform.parent = prefabPainter.container.transform;

                offsetLane++;
            }

            return(instance);
        }
Example #2
0
        public PrefabSettings GetPrefabSettings()
        {
            PrefabSettings selectedItem = GetRandomWeightedPrefab();

            if (selectedItem == null)
            {
                Debug.LogError("No prefab is active! At least 1 prefab must be active.");
                return(null);
            }

            return(selectedItem);
        }
Example #3
0
        private void AddPrefab(GameObject prefab, PrefabSettingsTemplate template)
        {
            // new settings
            PrefabSettings prefabSettings = new PrefabSettings();

            prefabSettings.ApplyTemplate(template);

            // initialize with dropped prefab
            prefabSettings.prefab = prefab;

            editor.newDraggedPrefabs.Add(prefabSettings);
        }
Example #4
0
        /// <summary>
        /// Ensure the prefab has a VegetationItemID
        /// </summary>
        /// <param name="prefabSettings"></param>
        private void updateVSProSettings(PrefabSettings prefabSettings, bool forceVegetationItemIDUpdate)
        {
#if VEGETATION_STUDIO_PRO
            GameObject prefab = prefabSettings.prefab;

            // check if we have a VegetationItemID, otherwise create it using the current prefab
            if (string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID) || forceVegetationItemIDUpdate)
            {
                // get the asset guid
                if (string.IsNullOrEmpty(prefabSettings.assetGUID))
                {
                    string assetPath = AssetDatabase.GetAssetPath(prefab);
                    if (!string.IsNullOrEmpty(assetPath))
                    {
                        string assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
                        prefabSettings.assetGUID = assetGUID;
                    }
                }

                // if we have a guid, get the vs pro id
                if (!string.IsNullOrEmpty(prefabSettings.assetGUID))
                {
                    // get the VegetationItemID
                    prefabSettings.vspro_VegetationItemID = VegetationStudioManager.GetVegetationItemID(prefabSettings.assetGUID);

                    // if the vegetation item id doesn't exist, create a new vegetation item
                    if (string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID))
                    {
                        VegetationType vegetationType     = VegetationType.Objects;
                        bool           enableRuntimeSpawn = false; // no runtime spawn, we want it spawned from persistent storage
                        BiomeType      biomeType          = BiomeType.Default;

                        prefabSettings.vspro_VegetationItemID = VegetationStudioManager.AddVegetationItem(prefab, vegetationType, enableRuntimeSpawn, biomeType);
                    }
                }
                else
                {
                    Debug.LogError("Can't get assetGUID for prefab " + prefab);
                }
            }

            if (string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID))
            {
                Debug.LogError("Can't get VegetationItemId for prefab " + prefab);
            }
#endif
        }
Example #5
0
        public void AddNewPrefab(PrefabSettings prefabSettings, Vector3 newPosition, Quaternion newRotation, Vector3 newLocalScale)
        {
#if VEGETATION_STUDIO_PRO
            // ensure the prefab has a VegetationItemID
            updateVSProSettings(prefabSettings, true);

            if (!string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID))
            {
                string     vegetationItemID  = prefabSettings.vspro_VegetationItemID;
                Vector3    worldPosition     = newPosition;
                Vector3    scale             = newLocalScale; // TODO local or world?
                Quaternion rotation          = newRotation;
                bool       applyMeshRotation = true;          // TODO ???
                float      distanceFalloff   = 1f;            // TODO ???
                bool       clearCellCache    = true;          // TODO ???

                byte vegetationSourceID = Constants.VegetationStudioPro_SourceId;

                VegetationStudioManager.AddVegetationItemInstance(vegetationItemID, worldPosition, scale, rotation, applyMeshRotation, vegetationSourceID, distanceFalloff, clearCellCache);
            }
#endif
        }
        public void OnInspectorGUI()
        {
            GUILayout.BeginVertical("box");
            {
                EditorGUILayout.LabelField("Prefabs", GUIStyles.BoxTitleStyle);

                GUILayout.BeginHorizontal();
                {
                    GUILayout.BeginVertical();
                    {
                        // change background color in case there are no prefabs yet
                        if (gizmo.prefabSettingsList.Count == 0)
                        {
                            editor.SetErrorBackgroundColor();
                        }

                        // drop area
                        Rect prefabDropArea = GUILayoutUtility.GetRect(0.0f, 34.0f, GUIStyles.DropAreaStyle, GUILayout.ExpandWidth(true));

                        // drop area box with background color and info text
                        GUI.color = GUIStyles.DropAreaBackgroundColor;
                        GUI.Box(prefabDropArea, "Drop prefabs here in order to use them", GUIStyles.DropAreaStyle);
                        GUI.color = GUIStyles.DefaultBackgroundColor;

                        editor.SetDefaultBackgroundColor();

                        Event evt = Event.current;
                        switch (evt.type)
                        {
                        case EventType.DragUpdated:
                        case EventType.DragPerform:

                            if (prefabDropArea.Contains(evt.mousePosition))
                            {
                                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                                if (evt.type == EventType.DragPerform)
                                {
                                    DragAndDrop.AcceptDrag();

                                    // list of new prefabs that should be created via drag/drop
                                    // we can't do it in the drag/drop code itself, we'd get exceptions like
                                    //   ArgumentException: Getting control 12's position in a group with only 12 controls when doing dragPerform. Aborting
                                    // followed by
                                    //   Unexpected top level layout group! Missing GUILayout.EndScrollView/EndVertical/EndHorizontal? UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
                                    // they must be added when everything is done (currently at the end of this method)
                                    editor.newDraggedPrefabs = new List <PrefabSettings>();

                                    foreach (Object droppedObject in DragAndDrop.objectReferences)
                                    {
                                        // allow only prefabs
                                        if (PrefabUtility.GetPrefabAssetType(droppedObject) == PrefabAssetType.NotAPrefab)
                                        {
                                            Debug.Log("Not a prefab: " + droppedObject);
                                            continue;
                                        }

                                        // new settings
                                        PrefabSettings prefabSettings = new PrefabSettings();

                                        // initialize with dropped prefab
                                        prefabSettings.prefab = droppedObject as GameObject;

                                        editor.newDraggedPrefabs.Add(prefabSettings);
                                    }
                                }
                            }
                            break;
                        }
                    }


                    GUILayout.EndVertical();
                }

                GUILayout.EndHorizontal();


                for (int i = 0; i < gizmo.prefabSettingsList.Count; i++)
                {
                    if (i > 0)
                    {
                        editor.addGUISeparator();
                    }

                    PrefabSettings prefabSettings = this.gizmo.prefabSettingsList[i];

                    GUILayout.BeginHorizontal();
                    {
                        // preview
                        // try to get the asset preview
                        Texture2D previewTexture = AssetPreview.GetAssetPreview(prefabSettings.prefab);
                        // if no asset preview available, try to get the mini thumbnail
                        if (!previewTexture)
                        {
                            previewTexture = AssetPreview.GetMiniThumbnail(prefabSettings.prefab);
                        }
                        // if a preview is available, paint it
                        if (previewTexture)
                        {
                            //GUILayout.Label(previewTexture, EditorStyles.objectFieldThumb, GUILayout.Width(50), GUILayout.Height(50)); // without border, but with size
                            GUILayout.Label(previewTexture, GUILayout.Width(50), GUILayout.Height(50)); // without border, but with size

                            //GUILayout.Box(previewTexture); // with border
                            //GUILayout.Label(previewTexture); // no border
                            //GUILayout.Box(previewTexture, GUILayout.Width(50), GUILayout.Height(50)); // with border and size
                            //EditorGUI.DrawPreviewTexture(new Rect(25, 60, 100, 100), previewTexture); // draws it in absolute coordinates
                        }

                        // right alin the buttons
                        GUILayout.FlexibleSpace();

                        if (GUILayout.Button("Add", EditorStyles.miniButton))
                        {
                            this.gizmo.prefabSettingsList.Insert(i + 1, new PrefabSettings());
                        }
                        if (GUILayout.Button("Duplicate", EditorStyles.miniButton))
                        {
                            PrefabSettings newPrefabSettings = prefabSettings.Clone();
                            this.gizmo.prefabSettingsList.Insert(i + 1, newPrefabSettings);
                        }
                        if (GUILayout.Button("Reset", EditorStyles.miniButton))
                        {
                            // remove existing
                            this.gizmo.prefabSettingsList.RemoveAt(i);

                            // add new
                            this.gizmo.prefabSettingsList.Insert(i, new PrefabSettings());
                        }
                        if (GUILayout.Button("Remove", EditorStyles.miniButton))
                        {
                            this.gizmo.prefabSettingsList.Remove(prefabSettings);
                        }
                    }
                    GUILayout.EndHorizontal();

                    GUILayout.Space(4);

                    prefabSettings.prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefabSettings.prefab, typeof(GameObject), true);

                    prefabSettings.active      = EditorGUILayout.Toggle("Active", prefabSettings.active);
                    prefabSettings.probability = EditorGUILayout.Slider("Probability", prefabSettings.probability, 0, 1);

                    // scale
                    prefabSettings.changeScale = EditorGUILayout.Toggle("Change Scale", prefabSettings.changeScale);

                    if (prefabSettings.changeScale)
                    {
                        prefabSettings.scaleMin = EditorGUILayout.FloatField("Scale Min", prefabSettings.scaleMin);
                        prefabSettings.scaleMax = EditorGUILayout.FloatField("Scale Max", prefabSettings.scaleMax);
                    }

                    // position
                    prefabSettings.positionOffset = EditorGUILayout.Vector3Field("Position Offset", prefabSettings.positionOffset);

                    // rotation
                    prefabSettings.rotationOffset = EditorGUILayout.Vector3Field("Rotation Offset", prefabSettings.rotationOffset);
                    prefabSettings.randomRotation = EditorGUILayout.Toggle("Random Rotation", prefabSettings.randomRotation);

                    // rotation limits
                    if (prefabSettings.randomRotation)
                    {
                        EditorGuiUtilities.MinMaxEditor("  Rotation Limit X", ref prefabSettings.rotationMinX, ref prefabSettings.rotationMaxX, 0, 360);
                        EditorGuiUtilities.MinMaxEditor("  Rotation Limit Y", ref prefabSettings.rotationMinY, ref prefabSettings.rotationMaxY, 0, 360);
                        EditorGuiUtilities.MinMaxEditor("  Rotation Limit Z", ref prefabSettings.rotationMinZ, ref prefabSettings.rotationMaxZ, 0, 360);
                    }

                    // VS Pro Id
#if VEGETATION_STUDIO_PRO
                    EditorGUI.BeginDisabledGroup(true);
                    EditorGUILayout.TextField("Asset GUID", prefabSettings.assetGUID);
                    EditorGUILayout.TextField("VSPro Id", prefabSettings.vspro_VegetationItemID);
                    EditorGUI.EndDisabledGroup();
#endif
                }
            }

            GUILayout.EndVertical();
        }
Example #7
0
        private void ApplyPrefabSettings(int offsetLane, PrefabSettings prefabSettings, GameObject prefab, Vector3 currentPosition, Vector3 direction, List <SplinePoint> splinePoints, int currentSplinePointIndex)
        {
            // add prefab's position offset
            prefab.transform.position += prefabSettings.positionOffset;

            // lanes
            Vector3    splinePosition = prefab.transform.position;
            Quaternion splineRotation = Quaternion.LookRotation(direction);

            Vector3 addDistanceToDirection = Vector3.zero;

            if (offsetLane == 0)
            {
                // check if the objects should be aligned next to each other
                // TODO this is only done for the center lane currently; we don't have the information about the others
                //      ie this only works in center lane mode currently
                if (prefabPainter.splineSettings.separation == SplineSettings.Separation.PrefabBounds)
                {
                    // move along in the spline rotation, considering the radius
                    addDistanceToDirection = splineRotation * prefab.transform.forward * GetDistanceToMove(prefab) / 2;
                }
            }
            // lane mode, all lanes except center
            else
            {
                // calculate offset distance to spline
                float offsetDistance = offsetLane * prefabPainter.splineSettings.laneDistance;

                // calculate the distance considering the spline direction
                //Vector3 distance = prefabPainter.splineSettings.lanePositionOffset - go.transform.position;
                addDistanceToDirection = splineRotation * prefab.transform.right * offsetDistance;
            }

            prefab.transform.position += addDistanceToDirection;


            // size
            if (prefabSettings.changeScale)
            {
                prefab.transform.localScale = Vector3.one * Random.Range(prefabSettings.scaleMin, prefabSettings.scaleMax);
            }

            // initial rotation
            Quaternion rotation = Quaternion.identity;

            switch (prefabPainter.splineSettings.instanceRotation)
            {
            case SplineSettings.Rotation.Spline:
                // rotation along spline
                rotation = Quaternion.LookRotation(direction);
                break;

            case SplineSettings.Rotation.Prefab:
                // rotation of the prefab
                if (prefabSettings.randomRotation)
                {
                    float rotationX = Random.Range(prefabSettings.rotationMinX, prefabSettings.rotationMaxX);
                    float rotationY = Random.Range(prefabSettings.rotationMinY, prefabSettings.rotationMaxY);
                    float rotationZ = Random.Range(prefabSettings.rotationMinZ, prefabSettings.rotationMaxZ);

                    rotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
                }
                break;
            }

            // lerp rotation between control points along the spline
            if (prefabPainter.splineSettings.controlPointRotation)
            {
                /*
                 * Quaternion controlPointRotation = prefabPainter.splineSettings.controlPoints[currentSplinePointIndex].rotation;
                 * rotation *= controlPointRotation;
                 */

                int currentControlPointIndex = splinePoints[currentSplinePointIndex].startControlPointIndex;
                int nextControlPointIndex    = currentControlPointIndex + 1;

                // check loop
                if (prefabPainter.splineSettings.loop)
                {
                    if (nextControlPointIndex > prefabPainter.splineSettings.controlPoints.Count - 1)
                    {
                        nextControlPointIndex = 0;
                    }
                }

                Vector3 currentControlPointPosition = prefabPainter.splineSettings.controlPoints[currentControlPointIndex].position;
                Vector3 nextControlPointPosition    = prefabPainter.splineSettings.controlPoints[nextControlPointIndex].position;

                // the percentage that a spline point is between control points. ranges from 0 to 1
                float percentageOnSegment = MathUtils.InverseLerp(currentControlPointPosition, nextControlPointPosition, currentPosition);

                // calculate lerp roation
                Quaternion currentControlPointRotation = prefabPainter.splineSettings.controlPoints[currentControlPointIndex].rotation;
                Quaternion nextControlPointRotation    = prefabPainter.splineSettings.controlPoints[nextControlPointIndex].rotation;

                Quaternion lerpRotation = Quaternion.Lerp(currentControlPointRotation, nextControlPointRotation, percentageOnSegment);

                // add rotation
                rotation *= lerpRotation;
            }

            prefab.transform.rotation = rotation;

            // add prefab rotation offset
            prefab.transform.Rotate(prefabSettings.rotationOffset);
        }
Example #8
0
        private void AddNewPrefab(Vector3 position, Vector3 normal)
        {
            GameObject container = gizmo.container as GameObject;

            PrefabSettings prefabSettings = this.gizmo.GetPrefabSettings();

            GameObject prefab = prefabSettings.prefab;

            ///
            /// Calculate position / rotation / scale
            ///

            // get new position
            Vector3 newPosition = position;

            // add offset
            newPosition += prefabSettings.positionOffset;

            Vector3 newLocalScale = prefabSettings.prefab.transform.localScale;

            // size
            if (prefabSettings.changeScale)
            {
                newLocalScale = Vector3.one * Random.Range(prefabSettings.scaleMin, prefabSettings.scaleMax);
            }

            // rotation
            Quaternion newRotation;

            if (prefabSettings.randomRotation)
            {
                float rotationX = Random.Range(prefabSettings.rotationMinX, prefabSettings.rotationMaxX);
                float rotationY = Random.Range(prefabSettings.rotationMinY, prefabSettings.rotationMaxY);
                float rotationZ = Random.Range(prefabSettings.rotationMinZ, prefabSettings.rotationMaxZ);

                newRotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
            }
            else if (this.gizmo.brushSettings.alignToTerrain)
            {
                newRotation = Quaternion.FromToRotation(Vector3.up, normal);
            }
            else
            {
                newRotation = Quaternion.Euler(prefabSettings.rotationOffset);
                //rotation = Quaternion.identity;
            }

            ///
            /// create instance and apply position / rotation / scale
            ///

            // spawn item to vs pro
            if (gizmo.brushSettings.spawnToVSPro)
            {
#if VEGETATION_STUDIO_PRO
                // ensure the prefab has a VegetationItemID
                updateVSProSettings(prefabSettings, true);

                if (!string.IsNullOrEmpty(prefabSettings.vspro_VegetationItemID))
                {
                    string     vegetationItemID   = prefabSettings.vspro_VegetationItemID;
                    Vector3    worldPosition      = position;
                    Vector3    scale              = newLocalScale; // TODO local or world?
                    Quaternion rotation           = newRotation;
                    bool       applyMeshRotation  = true;          // TODO ???
                    byte       vegetationSourceID = 5;             // TODO see PersistentVegetationStorageTools for constants. 5 = "Vegetation Studio - Painted"
                    float      distanceFalloff    = 1f;            // TODO ???
                    bool       clearCellCache     = true;          // TODO ???

                    VegetationStudioManager.AddVegetationItemInstance(vegetationItemID, worldPosition, scale, rotation, applyMeshRotation, vegetationSourceID, distanceFalloff, clearCellCache);
                }
#endif
            }
            // spawn item to scene
            else
            {
                // new prefab
                GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;

                instance.transform.position   = newPosition;
                instance.transform.rotation   = newRotation;
                instance.transform.localScale = newLocalScale;

                // attach as child of container
                instance.transform.parent = container.transform;

                Undo.RegisterCreatedObjectUndo(instance, "Instantiate Prefab");
            }
        }
        private void AddNewPrefab(Vector3 position, Vector3 normal)
        {
            GameObject container = editorTarget.container as GameObject;

            PrefabSettings prefabSettings = this.editorTarget.GetPrefabSettings();

            GameObject prefab = prefabSettings.prefab;

            ///
            /// Calculate position / rotation / scale
            ///

            // get new position
            Vector3 newPosition = position;

            // add offset
            newPosition += prefabSettings.positionOffset;

            // auto physics height offset
            newPosition = ApplyAutoPhysicsHeightOffset(newPosition);

            Vector3 newLocalScale = prefabSettings.prefab.transform.localScale;

            // size
            if (prefabSettings.changeScale)
            {
                newLocalScale = Vector3.one * Random.Range(prefabSettings.scaleMin, prefabSettings.scaleMax);
            }

            // rotation
            Quaternion newRotation;

            if (prefabSettings.randomRotation)
            {
                float rotationX = Random.Range(prefabSettings.rotationMinX, prefabSettings.rotationMaxX);
                float rotationY = Random.Range(prefabSettings.rotationMinY, prefabSettings.rotationMaxY);
                float rotationZ = Random.Range(prefabSettings.rotationMinZ, prefabSettings.rotationMaxZ);

                newRotation = Quaternion.Euler(rotationX, rotationY, rotationZ);
            }
            else if (this.editorTarget.brushSettings.alignToTerrain)
            {
                newRotation = Quaternion.FromToRotation(Vector3.up, normal);
            }
            else
            {
                newRotation = Quaternion.Euler(prefabSettings.rotationOffset);
                //rotation = Quaternion.identity;
            }

            ///
            /// create instance and apply position / rotation / scale
            ///

            // spawn item to vs pro
            if (editorTarget.brushSettings.spawnToVSPro)
            {
                vegetationStudioProIntegration.AddNewPrefab(prefabSettings, newPosition, newRotation, newLocalScale);
            }
            // spawn item to scene
            else
            {
                // new prefab
                GameObject instance = PrefabUtility.InstantiatePrefab(prefab) as GameObject;

                instance.transform.position   = newPosition;
                instance.transform.rotation   = newRotation;
                instance.transform.localScale = newLocalScale;

                // attach as child of container
                instance.transform.parent = container.transform;

                Undo.RegisterCreatedObjectUndo(instance, "Instantiate Prefab");

                if (editorTarget.spawnSettings.autoSimulationType != SpawnSettings.AutoSimulationType.None)
                {
                    autoPhysicsCollection.Add(instance);
                }
            }
        }