Ejemplo n.º 1
0
    // Method called to serialize a Spline Settings object
    public void GetObjectData(System.Object obj,
                              SerializationInfo info, StreamingContext context)
    {
        SplineSettings settings = (SplineSettings)obj;

        info.AddValue("name", settings.name);
    }
Ejemplo n.º 2
0
    //Generates a mesh along a spline. The mesh is defined in the settings at index i
    private void GenerateMesh(Transform splineParent, SplineSettings settings, int spline, int i)
    {
        GeneratedMesh meshSettings = settings.generated[i];
        string        name         = meshSettings.name;

        if (name.Length == 0)
        {
            name = string.Concat("Generated Mesh ", i.ToString("D2"));
        }
        name = string.Concat(i.ToString("D2"), "-", name);
        Transform newGenerated = splineParent.Find(name);

        //Create a new GameObject if there is none in the current scene
        if (newGenerated == null)
        {
            newGenerated               = new GameObject().transform;
            newGenerated.parent        = splineParent;
            newGenerated.localPosition = Vector3.zero;
            newGenerated.localRotation = Quaternion.identity;
            newGenerated.localScale    = Vector3.one;
            newGenerated.name          = name;
            newGenerated.gameObject.AddComponent <MeshFilter>();
            newGenerated.gameObject.AddComponent <MeshRenderer>();
        }

        //Update mesh and material
        newGenerated.GetComponent <MeshFilter>().mesh       = meshSettings.Generate(splines[spline]);
        newGenerated.GetComponent <MeshRenderer>().material = meshSettings.material;
    }
    //Initialize from file
    public static void Init(SplineSettings _settings)
    {
        SplineSettingsEditorWindow window = (SplineSettingsEditorWindow)EditorWindow.GetWindow(typeof(SplineSettingsEditorWindow));

        window.minSize   = new Vector2(600, 300);
        window.viewIndex = -1;
        settings         = _settings;
    }
Ejemplo n.º 4
0
 public void SetSettings(SplineSettings _settings)
 {
     settings      = _settings;
     assetIsActive = new bool[settings.generated.Count + settings.placers.Count];
     for (int i = 0; i < assetIsActive.Length; i++)
     {
         assetIsActive[i] = true;
     }
 }
    //Open a new SplineSettings asset
    private void OpenSplineSettings()
    {
        string absPath = EditorUtility.OpenFilePanel("Select Spline Settings", "Assets/", "asset");

        if (absPath.StartsWith(Application.dataPath))
        {
            string relPath = absPath.Substring(Application.dataPath.Length - "Assets".Length);
            settings = AssetDatabase.LoadAssetAtPath(relPath, typeof(SplineSettings)) as SplineSettings;
        }
    }
Ejemplo n.º 6
0
    // inspector for SplineSettings only shows a list of assetnames
    public override void OnInspectorGUI()
    {
        SplineSettings settings = target as SplineSettings;

        string[] assets = settings.GetAssetNames();
        foreach (string asset in assets)
        {
            GUILayout.Label(asset);
        }
    }
Ejemplo n.º 7
0
    private void DrawSplineInspector()
    {
        if (activeSpline >= 0)
        {
            GUILayout.Label("Spline:");
            EditorGUI.indentLevel++;

            EditorGUI.BeginChangeCheck();
            string name = EditorGUILayout.TextField("Name", component.GetSplineName(activeSpline));
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(component, "Change spline name");
                EditorUtility.SetDirty(component);
                component.SetSplineName(activeSpline, name);
            }

            EditorGUI.BeginChangeCheck();
            SplineSettings settings = (SplineSettings)EditorGUILayout.ObjectField("Settings", component.GetSplineSettings(activeSpline), typeof(SplineSettings), true);
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(component, "Change spline settings");
                EditorUtility.SetDirty(component);
                component.SetSplineSettings(activeSpline, settings);
            }

            EditorGUI.indentLevel--;
            EditorGUILayout.Space();

            if (settings != null)
            {
                GUILayout.Label("Active assets:");
                EditorGUI.indentLevel++;

                bool[] ActiveAssets = component.GetActiveAssets(activeSpline);
                EditorGUI.BeginChangeCheck();
                for (int i = 0; i < settings.generated.Count; i++)
                {
                    ActiveAssets[i] = EditorGUILayout.Toggle(settings.generated[i].name, ActiveAssets[i]);
                }
                for (int i = 0; i < settings.placers.Count; i++)
                {
                    ActiveAssets[i + settings.generated.Count] = EditorGUILayout.Toggle(settings.placers[i].name, ActiveAssets[i + settings.generated.Count]);
                }
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(component, "Change active assets");
                    EditorUtility.SetDirty(component);
                    component.SetActiveAssets(activeSpline, ActiveAssets);
                    ResetGeneratedContent();
                }
                EditorGUI.indentLevel--;
                EditorGUILayout.Space();
            }
        }
    }
Ejemplo n.º 8
0
 //Constructor using position and index in component
 public Spline(Vector3 position, int index)
 {
     points = new List <ControlPoint> {
         new ControlPoint(position, Vector3.forward),
         new ControlPoint(position + Vector3.forward, Vector3.forward)
     };
     ResetArcLengthTable();
     name          = string.Concat("Spline_", index.ToString("D2"));
     settings      = null;
     assetIsActive = null;
 }
Ejemplo n.º 9
0
    private static int tableSize = 100; //Precision value for the table

    //Constructor
    public Spline()
    {
        points = new List <ControlPoint> {
            new ControlPoint(Vector3.forward, Vector3.forward),
            new ControlPoint(Vector3.forward * 2, Vector3.forward)
        };
        ResetArcLengthTable();
        name          = string.Concat("Spline");
        settings      = null;
        assetIsActive = null;
    }
Ejemplo n.º 10
0
 //Update each spline that uses a given SplineSettings
 public void UpdateSpline(SplineSettings settings)
 {
     for (int i = 0; i < splineCount; i++)
     {
         if (splines[i].GetSettings() == settings)
         {
             SetSplineSettings(i, settings);
             UpdateSpline(i);
         }
     }
 }
Ejemplo n.º 11
0
    public static bool OnOpenAsset(int instanceID, int line)
    {
        SplineSettings settings = Selection.activeObject as SplineSettings;

        if (settings != null)
        {
            SplineSettingsEditorWindow.Init(settings); // Open editor window
            return(true);                              //catch open file
        }

        return(false); // let unity open the file
    }
Ejemplo n.º 12
0
    // Method called to deserialize a Spline Settings object
    public System.Object SetObjectData(System.Object obj,
                                       SerializationInfo info, StreamingContext context,
                                       ISurrogateSelector selector)
    {
        SplineSettings settings = (SplineSettings)obj;
        string         name     = (string)info.GetString("name");

        string[] assets = AssetDatabase.FindAssets(string.Concat(name, " t:SplineSettings"));
        if (assets.Length > 0)
        {
            settings = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(assets[0]), typeof(SplineSettings)) as SplineSettings;
            obj      = settings;
        }
        return(obj);   // Formatters ignore this return value //Seems to have been fixed!
    }
Ejemplo n.º 13
0
    //Generates all procedural obejcts for a spline
    private void ApplySettings(int index)
    {
        Transform      splineParent = transform.Find(GetSplineName(index));
        SplineSettings settings     = GetSplineSettings(index);

        if (splineParent == null)
        {
            splineParent = AddGeneratedBranch(index);
        }
        if (settings.assetCount < splineParent.childCount)
        {
            foreach (Transform child in splineParent)
            {
                string   childName   = child.name.Split('-')[1];
                string[] assetNames  = settings.GetAssetNames();
                bool     activeAsset = false;
                for (int i = 0; i < assetNames.Length; i++)
                {
                    if (childName == assetNames[i])
                    {
                        activeAsset = true;
                    }
                }
                if (!activeAsset)
                {
                    DestroyImmediate(child.gameObject);
                    Resources.UnloadUnusedAssets();
                }
            }
        }
        for (int i = 0; i < settings.generated.Count; i++)
        {
            if (splines[index].assetIsActive[i])
            {
                GenerateMesh(splineParent, settings, index, i);
            }
        }
        for (int i = 0; i < settings.placers.Count; i++)
        {
            if (splines[index].assetIsActive[settings.generated.Count + i] && settings.placers[i].objectReference != null)
            {
                PlaceObjects(splineParent, settings, index, i);
            }
        }
    }
    private void OnGUI()
    {
        EditorGUI.BeginChangeCheck();

        EditorGUILayout.Space();

        //Draw top bar with name and open & close buttons
        GUILayout.BeginHorizontal();
        string name = "No asset selected";

        if (settings != null)
        {
            name = settings.name;
        }
        GUILayout.Label(name);
        if (GUILayout.Button("Open", GUILayout.Width(100f)))
        {
            OpenSplineSettings();
        }
        if (GUILayout.Button("Close", GUILayout.Width(100f)))
        {
            settings = null;
        }
        GUILayout.EndHorizontal();
        EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

        //Draw editor if a settings asset is selected
        if (settings != null)
        {
            GUILayout.BeginHorizontal();

            //Left panel
            scrollposition = EditorGUILayout.BeginScrollView(scrollposition, false, true, GUILayout.Width(position.width / 2), GUILayout.Height(position.height - 30));
            string[] names = settings.GetAssetNames();

            //Generated meshes list
            GUILayout.Label("Generated meshes:");
            for (int i = 0; i < settings.generated.Count; i++)
            {
                string assetName = "";
                try {
                    assetName = names[i];
                }
                catch (IndexOutOfRangeException) {
                    //Cloning a asset can take longer then one GUI frame. In this case the amount of names given by GetAssetNames is less then the amount of assets.
                    //This problem fixes itselve in the next frame.
                }
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label(assetName, GUILayout.Width(position.width / 2 - 215));
                if (GUILayout.Button("Edit", GUILayout.Width(60)))
                {
                    viewIndex = i;
                    GUIUtility.keyboardControl = 0;
                }
                if (GUILayout.Button("Clone", GUILayout.Width(60)))
                {
                    settings.CloneGeneratedMesh(i);
                    viewIndex = i + 1;
                    GUIUtility.keyboardControl = 0;
                }
                if (GUILayout.Button("Remove", GUILayout.Width(60)))
                {
                    settings.generated.RemoveAt(i);
                    viewIndex = -1;
                    GUIUtility.keyboardControl = 0;
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("", GUILayout.Width(position.width / 2 - 87));
            if (GUILayout.Button("Add", GUILayout.Width(60)))
            {
                settings.AddGeneratedMesh();
                viewIndex = settings.generated.Count - 1;
                GUIUtility.keyboardControl = 0;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();

            //Object placers list
            GUILayout.Label("Object Placers:");
            for (int i = settings.generated.Count; i < names.Length; i++)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label(names[i], GUILayout.Width(position.width / 2 - 215));
                if (GUILayout.Button("Edit", GUILayout.Width(60)))
                {
                    viewIndex = i;
                    GUIUtility.keyboardControl = 0;
                }
                if (GUILayout.Button("Clone", GUILayout.Width(60)))
                {
                    settings.CloneObjectPlacer(i - settings.generated.Count);
                    viewIndex = i + 1;
                    GUIUtility.keyboardControl = 0;
                }
                if (GUILayout.Button("Remove", GUILayout.Width(60)))
                {
                    settings.placers.RemoveAt(i - settings.generated.Count);
                    viewIndex = -1;
                    GUIUtility.keyboardControl = 0;
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("", GUILayout.Width(position.width / 2 - 87));
            if (GUILayout.Button("Add", GUILayout.Width(60)))
            {
                settings.AddObjectPlacer();
                viewIndex = settings.assetCount - 1;
                GUIUtility.keyboardControl = 0;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            EditorGUILayout.EndScrollView();

            //Right panel
            GUILayout.BeginVertical();
            if (viewIndex >= 0 && viewIndex < settings.assetCount)
            {
                if (viewIndex < settings.generated.Count)
                {
                    DrawGeneratedMeshSettings(settings.generated[viewIndex]);
                }
                else
                {
                    DrawObjectPlacerSettings(settings.placers[viewIndex - settings.generated.Count]);
                }
            }
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
        }

        if (EditorGUI.EndChangeCheck())
        {
            if (settings)
            {
                EditorUtility.SetDirty(settings);
                SplineComponent[] components = FindObjectsOfType <SplineComponent>();
                foreach (SplineComponent component in components)
                {
                    component.UpdateSpline(settings);
                }
            }
        }
    }
Ejemplo n.º 15
0
    //Places objects along a spline. The object is defined in the settings at index i
    private void PlaceObjects(Transform splineParent, SplineSettings settings, int spline, int i)
    {
        ObjectPlacer objectSettings = settings.placers[i];

        string name = objectSettings.name;

        if (name.Length == 0)
        {
            name = objectSettings.objectReference.name;
        }
        name = string.Concat((settings.generated.Count + i).ToString("D2"), "-", name);

        //Get branch transform for current object, or create one if it does not exist
        Transform objectParent = null;

        foreach (Transform parent in splineParent)
        {
            if (parent.name == name)
            {
                objectParent = parent;
            }
        }
        if (objectParent == null)
        {
            objectParent               = new GameObject().transform;
            objectParent.parent        = splineParent;
            objectParent.localPosition = Vector3.zero;
            objectParent.localRotation = Quaternion.identity;
            objectParent.localScale    = Vector3.one;
            objectParent.name          = name;
        }

        int     child        = 0;
        Vector3 lastPosition = Vector3.one * float.MaxValue;

        //Loop along the length of the spline
        for (float j = objectSettings.offset;
             j < splines[spline].GetArcLength() - objectSettings.offset;
             j += objectSettings.distance)
        {
            //Get the transform of the child, or create one if it does not exist
            Transform newObject;
            if (objectParent.childCount > child)
            {
                newObject = objectParent.GetChild(child);
            }
            else
            {
                newObject        = (Transform)PrefabUtility.InstantiatePrefab(objectSettings.objectReference);
                newObject.parent = objectParent;
                newObject.gameObject.hideFlags = HideFlags.DontSaveInEditor;
            }

            //Calculate the position of this child
            Vector3 forward  = splines[spline].GetDirection(j).normalized;
            Vector3 up       = splines[spline].GetUp(j).normalized;
            Vector3 right    = Vector3.Cross(forward, up).normalized;
            Vector3 position = splines[spline].GetPoint(j) + right * objectSettings.position.x + up * objectSettings.position.y;

            //When type is set to global distance, the position needs to be recalculated
            if (objectSettings.type == offsetType.globalDistance)
            {
                if (lastPosition.x < float.MaxValue)
                {
                    //To fix the distance, it gets devided by the distance it had using the arcDistance calculation
                    float realDistance = (lastPosition - position).magnitude;
                    j += objectSettings.distance / realDistance;

                    forward  = splines[spline].GetDirection(j).normalized;
                    up       = splines[spline].GetUp(j).normalized;
                    right    = Vector3.Cross(forward, up).normalized;
                    position = splines[spline].GetPoint(j) + right * objectSettings.position.x + up * objectSettings.position.y;
                }
                lastPosition = position;
            }

            //Calculate rotation
            Vector3 splineRotation = Spline.GetEulerAngles(up, forward);
            if (!objectSettings.constraints[0])
            {
                splineRotation.x = 0;
            }
            if (!objectSettings.constraints[1])
            {
                splineRotation.y = 0;
            }
            if (!objectSettings.constraints[2])
            {
                splineRotation.z = 0;
            }
            Quaternion rotation = Quaternion.Euler(splineRotation) * Quaternion.Euler(objectSettings.rotation);

            //Calculate scale
            Vector3 scale = objectSettings.objectReference.localScale;
            scale.Scale(objectSettings.scale);

            newObject.position   = transform.TransformPoint(position);
            newObject.rotation   = transform.rotation * rotation;
            newObject.localScale = scale;

            child++;
        }
        // Loop through all remaining children and delete them if they are no longer on the spline
        while (objectParent.childCount > child)
        {
            DestroyImmediate(objectParent.GetChild(child).gameObject);
        }
    }
Ejemplo n.º 16
0
 public void SetSplineSettings(int index, SplineSettings settings)
 {
     splines[index].SetSettings(settings);
     UpdateSpline(index);
 }