I created a script with [ExecuteInEditMode] and some properties (get, set and private variable). Run.
The problem is that every time I load the scene these properties are reset to the default values.
How do I preserve the parameters entered?
Unity does not serialize properties, and it only serializes private variables if you decorate them with [SerializeField]
I tried to add [SerializeField] to the private fields, it still does not preserve the values entered. These are GameOject, Vector2 and Vector2Int. To display the fields in the inspector I use a CustomEditor.
Currently the properties are like
[SerializeField] private GameObject Prf___;
public GameObject Prf
{
get
{
return Prf___;
}
set
{
if (Prf___ == value) return;
Prf___ = value;
// some op
}
}
and…
[CustomEditor(typeof(MyClass))]
public class CE_MyClass : Editor
{
public override void OnInspectorGUI()
{
GUIStyle style = new GUIStyle
{
richText = true
};
MyClass man = (MyClass)target;
man.Prf = (GameObject)EditorGUILayout.ObjectField("MyPrf", man.Prf, typeof(GameObject), true);
DrawDefaultInspector();
}
}
in the same file, all wrapped up in #if UNITY_EDITOR
Just to be clear about this: you DO need to save the scene. This is only serialization that takes place at editor time, NOT at runtime. You cannot use this type of serialization for runtime game saving, for example.
Next step is to identify where this value is written to disk. Easiest way when using source control is to commit ALL your work, change the value, save the scene, then see that the disk asset did indeed change.
I save the scene, otherwise Unity would ask me to save it.
I only use the script to compose the scene (in the editor): once the sets run the script, the objects are correctly placed and obviously at runtime they are there. I would like to save the values because the script is able to change the objects previously entered and with different parameters the objects will be different.
The thing is that I tell it to save the scene but it doesn’t save the serialized private parameters. I have no need to store the state of the scene at runtime.
And of course the objects generated by the script are saved in the scene.
I don’t commit: it’s all just on my local disk and I use another backup method. The problem is not here.
I noticed, by analyzing the scene file, that if in the inspector I modify the private Vector2 variables they are saved, if, on the other hand, I modify the Vector2 via the CustomEditor they are not modified.
Strangely, only in this case, even if I modified Prf via the property, it saved it.
Are you dirtying them? There’s a set dirty call to do, or you can use Undo.RecordObject() to inform Unity that they need to be serialized.
I am not sure what a dirty object is, although I have read Unity - Scripting API: EditorUtility.SetDirty but I don’t think this is my case.
Basically it tells Unity that the object has been altered, and that it should write its data to disk (ergo, saving).
Show us the code being run in ExecuteInEditMode. 99% if you’re editing the values of an object via code and not through the inspector, you’ll need to dirty it so Unity knows its been edited.
[ExecuteInEditMode]
public class MyClass: MonoBehaviour
{
[SerializeField] private GameObject Prf___;
public GameObject Prf
{
get
{
return Prf___;
}
set
{
if (Prf___ == value) return;
Prf___ = value;
// some op
}
}
...
}
Okay… and what’s getting and setting these values? Posting a small portion of the code doesn’t much help us.
Nonetheless what I said above still applies. You probably want to use EditorUtility.SetDirty();
surrounded by #if UNITY_EDITOR
pre-processor directives.
Good. Seems to be working.
Thank you!