How to generate objects from a script in the editor, i.e. before runtime?

I’m making a “rope” object, which is comprised of a series of links and hinges. The formation is like this:

Link
Hinge
Link

Links are just capsules with a Rigidbody, and Hinges are capsules that have two Hinge Joints, one linked to the link above it, one connected to the link below.

The result is a physics-based rope (more of a chain, to be honest) that swings at each Hinge as you’d expect.

Here’s a screenshot of the Rope to help visualize:

Obviously it’s tedious to manually add Links and Hinges to increase the length of the rope. So, what I want to be able to do is edit the parameters of this rope in the inspector and have its script add Links and Hinges automatically.

My understanding is that I can run some script in editor to achieve this.

I currently have a script called “Rope” on an empty GameObject, with the expectation of generating the Rope Components (Links and Hinges) as children.

Here’s the Rope script as it stands…

[ExecuteInEditMode]
public class Rope : MonoBehaviour
{
    GameObject[] components = Resources.LoadAll<GameObject>("RopeComponents");

    [SerializeField] int ropeLength;
    [SerializeField] int numberOfLinks;

    public void CreateNewSection(Vector3 pos)
    {
        var newHinge = Instantiate(components[0],gameObject.transform);
        var newLink = Instantiate(components[1], gameObject.transform);

        MoveComps(newHinge, newLink, pos);

        var hinges = newHinge.GetComponents<HingeJoint>();
        hinges[1].connectedBody = newLink.GetComponent<Rigidbody>();
    }

    void MoveComps(GameObject hinge, GameObject link, Vector3 pos)
    {
        hinge.transform.position = pos;
        link.transform.position = pos + Vector3.down;
    }
}

I also have an EditorScript to make a button so that I can run the CreateNewSection method from the Rope script: (Warning: it’s totally in shambles, as this is the part of the process I really don’t understand…)

using UnityEditor;

[CustomEditor(typeof(Rope))]
public class RopeEditor : Editor
{
    SerializedObject ropeObj;

    public override void OnInspectorGUI()
    {
        rope = serializedObject;
        DrawDefaultInspector();
        DrawRopeEditor();
    }

    void DrawRopeEditor()
    {
        GUILayout.Space(5);
        GUILayout.Label("Rope Editor", EditorStyles.boldLabel);

        DrawCommitButton();
    }

    void DrawCommitButton()
    {
        if (GUILayout.Button(text: "Commit"))
        {
            rope.CreateNewSection(Vector3.zero);
        }

    }
}

Anyone have experience writing Editor Scripts and procedurally building objects like this?

The problem with the current way I’m attempting this is that I don’t know how to reference my Rope script from my editor script so that I can call the CreateNewSection() method.

Thanks for reading, and let me know if you have any thoughts!

You can initialize your rope in Start() or Awake() where you can read the rope length and number of links which have been adjusted from the inspector. I don’t think you need to mess with the editor itself.

Try this tutorial:

But if you really need to deal with the editor, try this: