Data from custom editor script is lost upon entering play mode

I’ve made an editor tool in unity by following a tutorial by Sebastian Lague and modified it to suit my needs. Basically, I form some polygons using gizmos in edit mode and save the data in a MonoBehaviour game object. It works fine, except that when I switch from edit to play mode, all the data stored in the MonoBehaviour object is lost.

I’ve been stuck on this for a while and noticed something really weird. I managed to save some data from edit to play mode by doing “Undo” and “Redo” before entering play mode. (I had implemented “Undo.RecordObject” functions in the editor script as per the tutorial). Only when I use “Undo” and “Redo” my polygons are saved and appear in play mode as they were in edit mode. Obviously, this seems very hacky and would like to find instead the “proper” way to fix the problem. However, I thought it could hint at what the solution is.

I tried googling my problem for many hours and found a few threads related to it. Every class I’m using to save the data in edit mode already has the [System.Serializable] attribute and all the class variables have [SerializeField]. I also tried marking the scene and the object that’s holding the data as “dirty” in OnInspectorGUI() in the editor script but it didn’t fix my problem.

I’m considering using a SerializedObject to hold the data instead of a MonoBehaviour but I’m not familiar with them at all so I don’t know if it’s the right call. Aside from that, I have no idea what to do next and any help is greatly appreciated. Thank you!

What exactly are you doing to mark the MonoBehaviour dirty?

You could use EditorUtility.SetDirty but the docs remark regarding scene objects:

It also mentions using SerializedObject/SerializedProperty instead of accessing the MonoBehaviour directly. This is often more tedious but also has benefits. They automatically handle dirtying, undo/redo and make it much easier to support multi-object editing.

if (GUI.changed)
{
      EditorUtility.SetDirty(target);
      EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
}

I’m doing it this way, in my editor script in OnInspectorGUI(). I know the documentation says it’s redundant with Undo.RecordObject which I was already using before I added this but I was desperate for a solution. I saw a post mentioning this fixed the problem I’m having but it didn’t change anything at all.

Nevermind, SetDirty was the correct solution after all. The problem was that in my case “OnInspectorGUI()” was the wrong place to call it.

I’m facing the same problem, where was the right place to call it?