Search Unity

Question ExecuteInEditMode lose parameters

Discussion in 'Editor & General Support' started by xtdiwd, May 19, 2022.

  1. xtdiwd

    xtdiwd

    Joined:
    Jul 25, 2020
    Posts:
    135
    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?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Unity does not serialize properties, and it only serializes private variables if you decorate them with [SerializeField]
     
  3. xtdiwd

    xtdiwd

    Joined:
    Jul 25, 2020
    Posts:
    135
    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
    Code (CSharp):
    1. [SerializeField] private GameObject Prf___;
    2.     public GameObject Prf
    3.     {
    4.         get
    5.         {
    6.             return Prf___;
    7.         }
    8.         set
    9.         {
    10.             if (Prf___ == value) return;
    11.             Prf___ = value;
    12.             // some op
    13.         }
    14.     }
    and...

    Code (CSharp):
    1. [CustomEditor(typeof(MyClass))]
    2. public class CE_MyClass : Editor
    3. {
    4.     public override void OnInspectorGUI()
    5.     {
    6.         GUIStyle style = new GUIStyle
    7.         {
    8.             richText = true
    9.         };
    10.         MyClass man = (MyClass)target;
    11.         man.Prf = (GameObject)EditorGUILayout.ObjectField("MyPrf", man.Prf, typeof(GameObject), true);
    12.         DrawDefaultInspector();
    13.     }
    14. }
    in the same file, all wrapped up in #if UNITY_EDITOR
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    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.
     
  5. xtdiwd

    xtdiwd

    Joined:
    Jul 25, 2020
    Posts:
    135
    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.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    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.
     
  7. xtdiwd

    xtdiwd

    Joined:
    Jul 25, 2020
    Posts:
    135
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,819
    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.
     
  9. xtdiwd

    xtdiwd

    Joined:
    Jul 25, 2020
    Posts:
    135
    This is my code

    Code (CSharp):
    1.    
    2. [ExecuteInEditMode]
    3.     public class MyClass: MonoBehaviour
    4.     {
    5.  
    6.  [SerializeField] private GameObject Prf___;
    7.         public GameObject Prf
    8.         {
    9.             get
    10.             {
    11.                 return Prf___;
    12.             }
    13.             set
    14.             {
    15.                 if (Prf___ == value) return;
    16.                 Prf___ = value;
    17.                 // some op
    18.             }
    19.         }
    20. ...
    21. }
    22.  
     
  10. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,819
    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.
     
  11. xtdiwd

    xtdiwd

    Joined:
    Jul 25, 2020
    Posts:
    135
    Good. Seems to be working.
    Thank you!