How to Have a ReoderableList in a Custom Editor Window

I’ve made two scripts, a custom editor window and a script containing a reoderable list, but I can’t put the list in the editor. The problem comes from the fact that the list script inherits from Editor, but the window script inherits from EditorWindow. How would I combine these?

ReoderableList Script:

using UnityEngine;
using UnityEditor;
using UnityEditorInternal;

[CustomEditor(typeof(LevelData))]
public class LevelDataEditor : Editor {
	private ReorderableList list;
	
	private void OnEnable() {
		list = new ReorderableList(serializedObject, 
        		serializedObject.FindProperty("Waves"), 
        		true, true, true, true);

        list.drawElementCallback = 
	        (Rect rect, int index, bool isActive, bool isFocused) => {
	        var element = list.serializedProperty.GetArrayElementAtIndex(index);
	        rect.y += 2;
	        EditorGUI.PropertyField(
    	        new Rect(rect.x, rect.y, 60, EditorGUIUtility.singleLineHeight),
            element.FindPropertyRelative("Type"), GUIContent.none);
	        EditorGUI.PropertyField(
    	        new Rect(rect.x + 60, rect.y, rect.width - 60 - 30, EditorGUIUtility.singleLineHeight),
                element.FindPropertyRelative("Prefab"), GUIContent.none);
	        EditorGUI.PropertyField(
    	        new Rect(rect.x + rect.width - 30, rect.y, 30, EditorGUIUtility.singleLineHeight),
                element.FindPropertyRelative("Count"), GUIContent.none);
        };

    list.drawHeaderCallback = (Rect rect) => {
	EditorGUI.LabelField(rect, "Monster Waves");

    list.onCanRemoveCallback = (ReorderableList l) => {
	return l.count > 1;
};

list.onRemoveCallback = (ReorderableList l) => {
	if (EditorUtility.DisplayDialog("Warning!", 
    	"Are you sure you want to delete the wave?", "Yes", "No")) {
		ReorderableList.defaultBehaviours.DoRemoveButton(l);
	}
};
};
	}
	
	public override void OnInspectorGUI() {
		serializedObject.Update();
		list.DoLayoutList();
		serializedObject.ApplyModifiedProperties();
	}
}

EditorWindow Script:

using UnityEditor;
using UnityEngine;
using UnityEditorInternal;

public class PathCreator : EditorWindow
{

    float ScaleX;
    float ScaleY;
    float OriginX;
    float OriginY;

    float smoothingScale = 1f;

    bool boundFoldout;
    bool active;
    bool smoothing;

    float spacing;

    Object m_MainCamera;

    Object subject;

    private ReorderableList list;
    
    //Location of the editor
    [MenuItem("Window/Path Creator")]
    public static void ShowWindow ()
    {
        GetWindow<PathCreator>("Path Creator");
    }

    void OnGUI ()
    {
        //Create ReoderableList
        list = new ReorderableList(serializedObject, serializedObject.FindProperty("Waves"), true, true, true, true);

        EditorGUI.indentLevel++;
        
        GUILayout.Label("Custom Camera Path", EditorStyles.boldLabel);
        
        //Active checkbox
        active = EditorGUI.Toggle(new Rect(3, 20, position.width, 20), "Active", active);
       
       //Check if active is true
       if(active)
       {
            smoothing = EditorGUI.Toggle(new Rect(3, 40, position.width, 20), "Edge Smoothing", smoothing);
            
            if (smoothing)
            {
                EditorGUI.indentLevel++;
                //Create smoothing slider
                smoothingScale = EditorGUI.Slider(new Rect(5, 70, 300, 20), "Smoothing", smoothingScale, 1, 100);     
                spacing = 80f;  
                EditorGUI.indentLevel--;         
            }
            else
            {
                spacing = 45f;
            }

            //Space accordingly
            EditorGUILayout.Space(spacing);
            
            //Create an empty field for Main Camera and Subject
            m_MainCamera = EditorGUILayout.ObjectField("Main Camera", m_MainCamera, typeof(Camera), true);
            subject = EditorGUILayout.ObjectField("Subject", subject, typeof(GameObject), true);

            //Create bounds foldout
            boundFoldout = EditorGUILayout.Foldout(boundFoldout,"Bounds");
            
            //Check if the bounds are folded
            if (boundFoldout)
            {
                EditorGUI.indentLevel++;
                ScaleX = EditorGUILayout.FloatField("Scale X", ScaleX);
                ScaleY = EditorGUILayout.FloatField("Scale Y", ScaleY);
                OriginX = EditorGUILayout.FloatField("Origin X", OriginX);
                OriginY = EditorGUILayout.FloatField("Origin Y", OriginY);
                EditorGUI.indentLevel--;
            }
       }
    }
}

Thanks <3

In order to have a built-in reorderable list using EditorWindow, just the same as the Editor you’ll need a separate class to hold the data, however, this class can be derived from the ScriptableObject class instead of MonoBehaviour so you don’t need to always have a GameObject in your scene carrying the script. Meanwhile, you can also have the class right inside the script you have your EditorWindow in.


Here is a very simple example of how it can be done:
MyEditorWindow.cs

    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    using UnityEditorInternal;
public class MyScriptableObject : ScriptableObject
{
	public List<string> strings = new List<string>();
}
public class MyEditorWindow : EditorWindow
{
	ReorderableList strings_ro_list;
	SerializedObject serializedObject;
	SerializedProperty stringsProperty;
	[MenuItem("Tools/Test Editor Window")]
	public static void ShowWindow()
	{
		GetWindow<MyEditorWindow>("Test Editor");
	}
	private void OnEnable()
	{
		MyScriptableObject obj = ScriptableObject.CreateInstance<MyScriptableObject >();
		
		serializedObject = new UnityEditor.SerializedObject(obj);
		stringsProperty= serializedObject.FindProperty("strings");
	
		strings_ro_list = new ReorderableList(serializedObject, stringsProperty, true, true, true, true);
		strings_ro_list.drawElementCallback = StringsDrawListItems;
		strings_ro_list.drawHeaderCallback = StringsDrawHeader;
	}
	private void OnGUI()
	{
		if (this.serializedObject == null)
		{
			return;
		}
		serializedObject.Update();
		strings_ro_list .DoLayoutList();
		serializedObject.ApplyModifiedProperties();
	}
	void StringsDrawListItems(Rect rect, int index, bool isActive, bool isFocused)
	{
		// your GUI code here for list content
	}
	void StringsDrawHeader(Rect rect)
	{
		// your GUI code here for list header
	}
}