How do I have an EditorWindow save it's data inbetween opening and closing Unity? C#

I am trying to make an EditorWindow that will store global data about my application, data which I want every level to be able to access. So my first route of going about this was to just make a static public class GlobalData. In it is all the data I want to store. Then in my EditorWindow I do a simple GlobalData.whatever this works in between opening and closing the EditorWindow. But not inbetween opening and closing Unity. It seems to not save changes to the variables in my static class. I do have [System.Serializable] put about my static class, and I have even tried calling SetDirty on my GlobalData data, but that doesn’t work.

From the advices of someone else I tried to create GlobalData NOT as a static, but rather just public. Then I create an Instance of GlobalData in my EditorWindow Class. But this does not save the data between opens and closes of even just the EditorWindow! I assume of course because the instance of GlobalData is being made in the EditorWindow so it loses that instance when it is closed.

I’ve tried messing around with making my GlobalData class a ScriptableObject, but that doesn’t work.

I’ve seriously spent like the past 18 hours sitting here trying any and everything I can think of and am running out of ideas :frowning: Please Help. If anyone could just give me the most base simple example code for an EditorWindow that somehow saves it’s data between open and closes of Unity, I would be so grateful. I cannot find any example projects anywhere that show how to do this.

And here is the code I’ve made thus far:

using UnityEngine;
using UnityEditor;

public class PanoSetup : EditorWindow
{
    [MenuItem ("Window/PanoSetup")]
    static void Init () {
        //PanoSetup window = 
		EditorWindow.GetWindow (typeof (PanoSetup));
    }

    void OnGUI () {
		GlobalData.texture = (Texture2D) EditorGUILayout.ObjectField(
            "Find Dependency",
            GlobalData.texture,
            typeof(Texture2D)); 
	}
}

using System.Collections;
using UnityEngine;

[System.Serializable]
static public class GlobalData {

	static public string texturePath = "temp";
	static public int what = 1;
	static public Texture2D texture = null;
	
}

You could use Unity’s serialization combined with JsonUtility and EditorPrefs to save your fields and then load them up in just 4 lines :

public class AnExampleWindow : EditorWindow
{
    [SerializeField] private Vector2 _someV2Field = Vector2.zero;
    [SerializeField] private Color _aBitOfColor = Color.green;
    [SerializeField] private List<Color> _aFlagColors = new List<Color> { Color.blue, Color.white, Color.red };
    [SerializeField] private bool _amIFrench = true;
    [SerializeField] private string _savePath = "Assets/Resources/anFlag.png";

    private string _aNotSerializedString;
    private int _aNotSerializedInt;

    protected void OnEnable ()
    {
        // Here we retrieve the data if it exists or we save the default field initialisers we set above
        var data = EditorPrefs.GetString("AnExampleWindow", JsonUtility.ToJson(this, false));
        // Then we apply them to this window
        JsonUtility.FromJsonOverwrite(data, this);
    }

    protected void OnDisable ()
    {
        // We get the Json data
        var data = JsonUtility.ToJson(this, false);
        // And we save it
        EditorPrefs.SetString("AnExampleWindow", data);

        // Et voilà !
    }


        // Your pretty code here...
}

Use EditorPrefs to save and load values. Load them in OnEnable and write them in OnDisable and you’re done.

There are several ways to do this. I would create a/several ScritpableObject and store them in your project’s Resources folder.

I’d make a class:

public class MyScriptableObjectClass : ScriptableObject
{
//Savable data here
}

Than I would save and load it using:

MyScriptableObjectClass myInstance = (MyScriptableObjectClass )Resources.Load("myInstance.asset") as MyScriptableObjectClass;
if(myInstance  == null)
{
myInstance = CreateInstance<MyScriptableObjectClass>();
 AssetDatabase.CreateAsset(myInstance , "Assets/Resources/myInstance.asset");
 AssetDatabase.SaveAssets();
         AssetDatabase.Refresh();
}

In The Game you could load the class from anywhere using MyScriptableObjectClass myInstance = (MyScriptableObjectClass )Resources.Load(“myInstance.asset”) as MyScriptableObjectClass;
and access the data there.

(Edit: Quick Note: The code I wrote is not tested code. I don’t know if it will work if you just copy paste it. But it will point you to the right classes to use.)

Well, i just saw that you want to store complex types (like texture references). Well another way would be to create a separate script that saves your variables to your assets. Just create a GameObject (set the hideflags) and attach your script to it (all done from within your editor-script). Use AssetDatabase and EditorUtility to save and load it as prefab.

This blog post tells you all about serializing objects for Editor scripts.