- Home /
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:
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++;
}
}
}
}
Answer by stepan-stulov · Aug 14, 2015 at 08:03 AM
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:
http://answers.unity3d.com/questions/641199/do-i-need-to-use-setdirty-in-my-editors-if-im-usin.html
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.
Thank you very much :) Everything is working perfectly now!
Thank you! I was having this same issue for a couple of weeks and this was all I needed!
Answer by eskivor · Nov 22, 2017 at 11:27 AM
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)
Removing AssetDatabase.Refresh() fixed this issue for me. I was loading a scriptableobject (which had a single asset, which was ONLY edited through the Inspector, outside of Play Mode.) On my computers, the Asset would survive Unity restarts / computer restarts, but for some reason, even though I was NOT modifying the scriptableObject in any scripts (only reading its data), another developer, when getting the updated Asset through git, Unity would reset the asset's (public) properties.
more details if anyone wants it https://forum.unity.com/threads/scriptableobject-asset-gets-reset-by-other-team-member-2019-4-2f1.1196113/