Outsource EditorWindow code

My current project is a 2D platformer for which I’m building a level-editor by using an EditorWindow.

In previous projects where I created editor tools I noticed that this can quickly lead to very long classes (2000+ loc) which is why this time I want to outsource certain functions into their own classes (e.g FileManagerPanel, LevelInformationPanel, BackgroundLayerPanel, etc) and just call the Draw method I implemented for each of them from within the main EditorWindow. References to instances of these Panel classes are created when the EditorWindow is opened (this way I can later implement Dependency Injection).

The problem is that some Panels still need to access other Panels (e.g. the LevelInformationPanel needs to read data from/write data to a ScriptableObject which is loaded in the FileManagerPanel). When everything was still in the same EditorWindow class I would just create a new SerializedObject and call its Update method, then add EditorGUILayout.PropertyField(serializedObject.FindProperty("VariableName")); and afterwards call the ApplyModifiedProperties method.

This works because the EditorWindow class itself derives from UnityEngine.Object and thus can be serialized. With my outsourced classes however, I noticed that it’s apparently not a good idea to inherit from UnityEngine.Object directly because the constructor will return null.
When deriving these classes from System.Object instead the constructor will work but not the PropertyField.

I think ScriptableObject would probably work but I’d need to create file instances within my Asset folder which is kind of ugly. Also maybe PropertyDrawers would work but I don’t like using them because it’s annoying having to specify all the rects myself instead of being able to use the Layout classes. Is there maybe another option?

An EditorWindow is also just a ScriptableObject. You should never derive any class from UnityEngine.Object. It’s just the base class for all objects that have a counterpart on the native C++ side. The only classes you should use as your baseclasses at runtime are MonoBehaviour and ScriptableObject. Of course in editor code we have some additional classes like EditorWindow and Editor (which are actually derived from ScriptableObject).

So you can just derive your classes from ScriptableObject. This will make your classes survive an assembly reload. If you create them in OnEnable only if they do not exist yet everything should be fine. Of course they won’t survive a scene change or closing Unity. If you want them to survive that as well you have to store them as assets.