Search Unity

  1. Curious about what's going to be in 2020.1? Have a look at the 2020.1 beta blog post.
    Dismiss Notice
  2. Want to see 2020.1b in action? Sign up for our Beta 2020.1 Overview Webinar on April 20th for a live presentation from our evangelists and a Q&A session with guests from R&D.
    Dismiss Notice
  3. Interested in giving us feedback? Join our online research interviews on a broad range of topics and share your insights with us.
    Dismiss Notice
  4. New Unity Live Help updates. Check them out here!

    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:
    8
    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.
     
  2. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    798
    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
     
    phobos2077, LeonhardP and Peter77 like this.
  3. pablo_leban

    pablo_leban

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

    Laicasaane

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

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    727
    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.
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,616
    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:
    647
    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:
    727
    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 at 10:45 AM
  9. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    647
    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:
    584
    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:
    727
    Indeed.
     
unityunity