0
\$\begingroup\$

After setting a field using the editor API, the field gets cleared on Play in Unity. How to fix it?

I have a menu item. That menu item sets a field on one of my game objects in scene. After the field was set I can see the correct value in editor and I save the scene. But whenever I Play my game from the editor the field gets reset to a default value forever.

I found a brief explanation of the reasons behind that here. In a nutshell before Play Unity is serializing my whole scene and for some reasons it misses the specific field which was set through the editor API. So, later on Unity loads (i.e. creates a copy of what was serialized) the serialized scene and performs the Play itself.

All that led me to try a trick, which actually worked. First, I change the field through the editor API. After that I change another random field using the editor itself and save a scene. Then I revert the random field value and save my scene once more. Now if I Play I get the field value preserved and I get what I am asking for in this question. But this way of doing things seems like a technical debt to me, so I was hoping that someone might suggest something better.

Also, neither the [System.Serializable], nor the [SerializeField] properties on that field did not help.

My guess is that while the editor API is executing I need to tell it to take into account the changed field somehow after it was changed. But I was not able to find out how to do that.

\$\endgroup\$
9
  • \$\begingroup\$ Show us your code for setting the field, so we can see where you use Undo.RecordObject or EditorUtility.SetDirty to record your changes for serialization. \$\endgroup\$
    – DMGregory
    Commented Jun 18, 2021 at 19:36
  • \$\begingroup\$ @DMGregory, the code is quite huge and there are a lot of unrelated pieces in it. Basically I grasp a game object in scene. I grasp a value for a property and do just this: gameObjectInScene.itsField = theFieldValue. GameObject itsField;. \$\endgroup\$
    – qqqqqqq
    Commented Jun 18, 2021 at 19:38
  • \$\begingroup\$ @DMGregory, it seems the Undo.RecordObject works as I need. Just curious where could I find the undo history? I mean the one to which I add the title: docs.unity3d.com/ScriptReference/Undo.RecordObject.html. \$\endgroup\$
    – qqqqqqq
    Commented Jun 18, 2021 at 19:41
  • \$\begingroup\$ If you've solved your problem, you can post your solution as an answer below. If you'd like to ask a new question, you can post it as a new question post, or edit the post above to ask that instead. Note that the documentation you linked explains this text is shown in the "Edit > Undo" menu option. \$\endgroup\$
    – DMGregory
    Commented Jun 18, 2021 at 19:42
  • 1
    \$\begingroup\$ That means that a selection change occurred after your Undo.RecordObject call. If you undo a few times to step back through the history, you'll find it in a previous step. \$\endgroup\$
    – DMGregory
    Commented Jun 18, 2021 at 19:51

1 Answer 1

0
\$\begingroup\$

After the @DMGregory♦ comment I come across this documentation.

So, to have the changes made through the editor API serialized correctly I did change this way:

Undo.RecordObject(gameObjectInScene, "Set reference for itsField.");
gameObjectInScene.itsField = theFieldValue;
PrefabUtility.RecordPrefabInstancePropertyModifications(gameObjectInScene);

And if after changing the field you would like to apply the field change to a prefab just add a fourth line:

PrefabUtility.ApplyPrefabInstance(gameObjectInScene, InteractionMode.UserAction);
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .