Scriptable Object resets after Unity is closed

Dear Unity-Comunity,

I have a problem with Scriptable Objects. I generate most of my UI meshes at runtime (like grids, lines, etc.) and I use a Scriptable Object to select the Materials. That makes it a lot easier to quickly change them. My probleme is, that every time I close Unity, the asset (instance of UIData) in my Ressources folder gets reset to these settings: 52023-inspector.png

Best Regards,
Théo

My Code:

UIData.cs


[System.Serializable]
public class UIData : ScriptableObject {
	[SerializeField]
	public Material Line;
	[SerializeField]
	public float LineThickness;

	[SerializeField]
	public Material UnitHighlight;
	[SerializeField]
	public Material WalkArea;
	[SerializeField]
	public Material RunArea;
	[SerializeField]
	public Material Grid;
}

UIDataEditor.cs


[CustomEditor(typeof(UIData))]
public class UIDataEditor : Editor {
	private static bool LineFoldout = true;

	public override void OnInspectorGUI()
	{
		UIData data = (UIData)target;	
		LineFoldout = EditorGUILayout.Foldout(LineFoldout, "Line");
		if(LineFoldout)
		{
			EditorGUI.indentLevel++;
			data.Line = EditorGUILayout.ObjectField("Line Material", data.Line, typeof(Material), false) as Material;
			data.LineThickness = EditorGUILayout.FloatField("Line Thickness", data.LineThickness);
			EditorGUI.indentLevel--;
		}
		data.UnitHighlight = EditorGUILayout.ObjectField("Unit Highlight Material", data.UnitHighlight, typeof(Material), false) as Material;
		data.Grid = EditorGUILayout.ObjectField("Grid Material", data.Grid, typeof(Material), false) as Material;	
		data.WalkArea = EditorGUILayout.ObjectField("Walk Area Material", data.WalkArea, typeof(Material), false) as Material;
		data.RunArea = EditorGUILayout.ObjectField("Run Area Material", data.RunArea, typeof(Material), false) as Material;
	}

	[MenuItem("Assets/Create/UI Data")]
	public static void CreateUIDataAsset()
	{
		Object asset = ScriptableObject.CreateInstance<UIData>();

		int i = 0;
		while(true)
		{
			if(AssetDatabase.FindAssets("t:UIData UIData" + i.ToString()).Length == 0)
			{
				AssetDatabase.CreateAsset(asset, "Assets/UIData" + i.ToString() +".asset");
				AssetDatabase.SaveAssets();
				EditorUtility.FocusProjectWindow();
				Selection.activeObject = asset;
				break;
			}
			else
			{
				i++;
			}
		}
	}
}

You’re not marking you scriptable object dirty after changing its values. Thus the values are not scheduled for serialization and thus are not surviving the reload. In the UIDataEditor.OnInspectorGUI you need to EditorUtility.SetDirty(target).

Check this post:

PS: You don’t need to mark public fields as [SerializeField] as publics are already automatically so. Unless of course you do it for the sake of programmer’s discipline. My normal workflow is [SerializeField] private fields + a getter + an optionally setter.

I had the same kind of problem, but I already used EditorUtility.SetDirty (); and AssetDatabase.SaveAssets(); but I had a problem using a AssetDatabase.Refresh (); between them (I removed it and it worked then)

Thank you so much!