Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Scriptable object persisting data. Bug or feature?

Discussion in '2020.1 Beta' started by pablo_leban, Mar 25, 2020.

  1. pablo_leban

    pablo_leban

    Joined:
    Sep 19, 2013
    Posts:
    68
    Hi. So whenever I edit a scriptable object variable, the new value persists through the Unity session. This means that if I have a scriptable object with a string value of "John", and during runtime I change that value to "Steve" through code by doing something like
    Code (CSharp):
    1. myScriptableObject.name = "Steve";
    then I stop playing, and play it again, the value will still be "Steve". However, if I restart Unity, the name will be "John" again.

    Is this a bug or a feature?

    Thanks.
     
    will_unity731 likes this.
  2. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,313
    It's correct behavior. I guess you would call it a feature.
    The reason it reverts to John after reloading unity is when you changed it to Steve, you didn't dirty the scriptable object.

    When unity exits (without crashing) or you hit "save project" unity writes dirty object values to disk.

    Since the object is not being set dirty from your runtime script, unity doesn't know anything has changed, so Steve is never written to disk.

    Solution... Use EditorUtility.SetDirty(yourObjectReference) after changing the value.

    Note this is editor only. If you change to Steve in built player. Steve will persist through the game session. If you close the app, the value will be John again
     
  3. pablo_leban

    pablo_leban

    Joined:
    Sep 19, 2013
    Posts:
    68
    Thanks for replying. That helped a lot. ;)
     
  4. Laicasaane

    Laicasaane

    Joined:
    Apr 15, 2015
    Posts:
    365
    In the Editor you should always instantiate scriptableobject before using it.
     
  5. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    Only if you are modifying it. There is no reason to instantiate immutable data ScriptableObjects, I would treat the mutation to be a bug in most of those uses.
     
    will_unity731 likes this.
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    This feature is really useful in order to allow live-editing of gameplay elements that persist after play mode. We usually set up UI settings (sizes, timings, etc.) in a ScriptableObject. The UI uses those settings, and listens to a callback on the SO that we invoke when we change it, so the changes live update.
     
    Laicasaane likes this.
  7. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,261
    I am making a project for drawing with the vector graphics package. I create my tools using scriptable objects, so I can set cursors for each one and other settings they may need. In my shape tool, I have an auto property used to define what shape is supposed to be drawn(uses an Enum.) I would select one shape, draw it. Then select another shape, draw that one and stop playing to make some changes. Every time I did this the last shape would be the one selected not the one I set as default. The only way to get it to revert the property back to default was to shut down the editor and start it back up again(domain reload.)

    In conclusion, ScriptableObjects get loaded in the editor and retain their values until a domain reload. In my case I don't want it to save or retain the changes, thus the use of an auto property. Had me scratching my head as to why Unity would be able to serialize a property when I know it can't.
     
  8. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    Just to frustrate you a little bit more, this isn't strictly true. Unity *does* serialize private fields during domain reload, and that does include auto property backing fields. Generally, anything you can see with the debug inspector is serialized, just not to disk. To lose those changes you need Unity to reload the asset from disk, as private fields are not serialized to disk.
     
    Last edited: Mar 31, 2020
    PitaBreadGames likes this.
  9. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,261
    It's only a small caveat with SO's in the editor. Once you understand that any SO shown in the inspector is deserialized and loaded into memory and remains in memory until the asset gets unloaded. If you have a reference to an SO in a scene it will also be deserialized with the scene when it gets deserialized.
     
  10. spacefrog

    spacefrog

    Joined:
    Jun 14, 2009
    Posts:
    734
    Lokking just for conformation ( or - hopefully not - dissent ), you can prevent serialization of private fields on SO's by using the [NonSerialized] Attribute ... correct ?
     
  11. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    Indeed.
     
  12. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    So to add to this, how can I mark a field to not be persisted but still show up in the inspector?