# ScriptableObject changes not persisted

**URL:** https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871
**Category:** Scripting
**Tags:** Scripting
**Created:** [December 23, 2016, 6:38am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871 "2016-12-23T06:38:46Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Sabo](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Sabo](https://discussions.unity.com/u/Sabo)
#### Post date: [December 23, 2016, 6:38am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/1 "2016-12-23T06:38:46Z")

</div>

I have a MonoBehaviour that references a ScriptableObject, ActionBarSlot. Changing the action bar slot through the UI during runtime doesn’t persist the change through a Unity re-opening. However, changing the action bar slot by manually dragging a talent onto it works well, both during runtime as well as non-runtime.

ActionBarSlot is referenced from ActionBarSlotUI (MonoBehaviour).  
Riposte is referenced from TalentTreeNode (MonoBehaviour).  
The talent is passed along the monobehavious unchanged, not casted to anything anywhere, through a drag event. Everything seems to line up perfectly and the ActionBarSlot gets the new talent. It just doesn’t persist for some reason.

What am I missing?

```csharp
public class Talent : ScriptableObject
{
    public string Description;
    public int Level;
    public int MaxLevel;
    public Sprite Icon;
    public List<Talent> Dependencies = new List<Talent>();
}

[CreateAssetMenu(menuName = "Game/Talents/Riposte")]
public class Riposte : Talent, IAction
{
    public int DamagePerLevel;
    public float Cooldown { get; set; }

    public Sprite GetIcon
    {
        get { return Icon; }
    }

    public void Perform(IActor caster)
    {
        if (caster == null)
        {
            throw new ArgumentNullException("caster");
        }

        Debug.Log("In Riposte, riposting...");
    }
}

public class ActionBarSlot : ScriptableObject
{
    private Item item;
    public Talent talent;
}

```

---

<div class="post-metadata">

### Author: ![Sabo](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Sabo](https://discussions.unity.com/u/Sabo)
#### Post date: [December 31, 2016, 3:59pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/2 "2016-12-31T15:59:23Z")

</div>

Bump.

---

<div class="post-metadata">

### Author: ![LaneFox](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/lanefox/32/42_2.png) [@LaneFox](https://discussions.unity.com/u/LaneFox)
#### Post date: [December 31, 2016, 4:07pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/3 "2016-12-31T16:07:21Z")

</div>

Changes during play mode are deliberately not persistent.

---

<div class="post-metadata">

### Author: ![TonyLi](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/tonyli/32/611093_2.png) [@TonyLi](https://discussions.unity.com/u/TonyLi)
#### Post date: [December 31, 2016, 9:28pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/4 "2016-12-31T21:28:29Z")

</div>

Changes during playmode to ScriptableObject _assets_ (files in your Project view) are persistent. For example:

```auto
[CreateAssetMenu]
public MySO : ScriptableObject {
    public int myNumber;
}

```

Let’s say you create an asset of this ScriptableObject type (MySO).

During playmode, if you inspect that asset in the Project view and change myNumber, it _will_ remain changed when you stop playing.

However, if you’ve instantiated (cloned) a copy of the asset, changes to the clone will not persist, and will not be copied back to the original asset. For example:

```auto
var clone = Instantiate(mySO);
clone.myNumber = 42; // Value be lost when stopping playmode.

```

> [@Sabo](#):
>
> Changing the action bar slot through the UI during runtime doesn’t persist the change through a Unity re-opening.

I’m guessing that you’ve written a custom editor for your ScriptableObject asset, and that it’s not marking the asset dirty. In this case, Unity doesn’t know to save the changes to disk. When you close Unity, those changes are lost. Ideally, your custom editor will use serializedObject.Update(), EditorGUI[Layout].PropertyField, and serializedObject.ApplyModifiedProperties(). These will properly mark the asset dirty. Or don’t use a custom editor at all, and use [Header], [Tooltip], etc., attributes for your serialized fields to get the look you want if possible.

---

<div class="post-metadata">

### Author: ![Baste](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/baste/32/880289_2.png) [@Baste](https://discussions.unity.com/u/Baste)
#### Post date: [January 1, 2017, 1:47am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/5 "2017-01-01T01:47:04Z")

</div>

The reference that’s not persisting is the reference in the MonoBehaviour, no?

As @LaneFox said, changes to object references on MonoBehaviours does not persist during play, by design. So if you drag-and-drop in a new ActionBarSlot to your MonoBehaviour during play, it’ll revert when you leave play.

This isn’t different from say changing the speed of an NPC at play - it won’t stay changed when you leave. You’re switching an object reference rather than a float, but the result is still the same.

Changing the ActionBarSlot itself _will_ persist, because it’s an asset. Changes to a prefab in the project overview will persist, as it’s also an asset.

---

<div class="post-metadata">

### Author: ![Sabo](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Sabo](https://discussions.unity.com/u/Sabo)
#### Post date: [January 4, 2017, 4:49am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/6 "2017-01-04T04:49:27Z")

</div>

> [@Baste](#):
>
> The reference that’s not persisting is the reference in the MonoBehaviour, no?

Bit too tired (or stupid) to be sure what you mean.

> [@Baste](#):
>
> As @LaneFox said, changes to object references on MonoBehaviours does not persist during play, by design. So if you drag-and-drop in a new ActionBarSlot to your MonoBehaviour during play, it’ll revert when you leave play.

Yeah, which is why I have begun to fall in love with Assets, for better or worse. In this case, I am not dropping in a new ActionBarSlot, merely changing a reference field in one of them, pointing to another Asset.

> [@Baste](#):
>
> This isn’t different from say changing the speed of an NPC at play - it won’t stay changed when you leave. You’re switching an object reference rather than a float, but the result is still the same.

This is assuming the speed is not an Asset , right?

> [@Baste](#):
>
> Changing the ActionBarSlot itself _will_ persist, because it’s an asset. Changes to a prefab in the project overview will persist, as it’s also an asset.

That is just it though, I believe I AM making a change to the specific asset, not changing it.

The current structure of it all is (under development while learning):  
Talent : ScriptableObject (works as base class for various talents, maybe that is the issue?)  
ActionBarSlot : ScriptableObject (has a Talent field which is supposed to be changed during runtime AND persisted)  
ActionBarSlotUI : MonoBehaviour (has an ActionBarSlot field, reference itself never changes)  
TalentTreeNode : MonoBehaviour (has a Talent field which is assigned during non-runtime)

I implement the standard bunch of Unity IXXXDragHandler’s to a TalentTreeNode. I then drop a node on an ActionBarSlotUI, at which point the ActionBarSlotUI gets the reference to the Talent and passes it along to the Talent field in the ActionBarSlot that it has a reference to. The only thing that change references during these operations is the Talent field in the ActionBarSlot, and given that it is an Asset I thought it would persist those changes. It is especially curious to me that, if I manually drag a talent, subtalents included, to the Talent field of an ActionBarSlot during runtime it WILL persist that change. It just does not work when I drag them using the ingame UI.

---

<div class="post-metadata">

### Author: ![Sabo](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Sabo](https://discussions.unity.com/u/Sabo)
#### Post date: [January 4, 2017, 5:02am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/7 "2017-01-04T05:02:21Z")

</div>

> [@TonyLi](#):
>
> Changes during playmode to ScriptableObject _assets_ (files in your Project view) are persistent. For example:
> 
> ```auto
> [CreateAssetMenu]
> public MySO : ScriptableObject {
> public int myNumber;
> }
> 
> ```
> 
> Let’s say you create an asset of this ScriptableObject type (MySO).
> 
> During playmode, if you inspect that asset in the Project view and change myNumber, it _will_ remain changed when you stop playing.
> 
> However, if you’ve instantiated (cloned) a copy of the asset, changes to the clone will not persist, and will not be copied back to the original asset. For example:
> 
> ```auto
> var clone = Instantiate(mySO);
> clone.myNumber = 42; // Value be lost when stopping playmode.
> 
> ```

Right. I do not instantiate any asset. Pre runtime I drag the assets (talents) onto talent tree nodes (have a reference to Talent asset). During runtime I drag talent tree nodes to action bar slots, setting a talent field to reference the talent in the talent tree node. Since all I am doing is changing the reference in the action bar slot slot (which is an asset) to point to another asset (talent) I would like to think that the change should be persisted. Especially since, during runtime, dragging the very same talent from the project view and dropping it on the talent field for the action bar slot asset DO persist the change. Just does not work when dropping it during the ingame UI. And oh, I never (as far I know) instantiate any asset of any kind during runtime, just changing fields in them. Hope I am not proven wrong!

> [@TonyLi](#):
>
> I’m guessing that you’ve written a custom editor for your ScriptableObject asset, and that it’s not marking the asset dirty. In this case, Unity doesn’t know to save the changes to disk. When you close Unity, those changes are lost. Ideally, your custom editor will use serializedObject.Update(), EditorGUI[Layout].PropertyField, and serializedObject.ApplyModifiedProperties(). These will properly mark the asset dirty. Or don’t use a custom editor at all, and use [Header], [Tooltip], etc., attributes for your serialized fields to get the look you want if possible.

No custom editor created (yet).

---

<div class="post-metadata">

### Author: ![Sabo](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Sabo](https://discussions.unity.com/u/Sabo)
#### Post date: [January 4, 2017, 5:02am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/8 "2017-01-04T05:02:59Z")

</div>

> [@LaneFox](#):
>
> Changes during play mode are deliberately not persistent.

Was under the impression that changes to Assets during gameplay DO persist?

---

<div class="post-metadata">

### Author: ![TonyLi](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/tonyli/32/611093_2.png) [@TonyLi](https://discussions.unity.com/u/TonyLi)
#### Post date: [January 4, 2017, 2:02pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/9 "2017-01-04T14:02:19Z")

</div>

> [@Sabo](#):
>
> Was under the impression that changes to Assets during gameplay DO persist?

Lane was talking about objects that get serialized when reloading assemblies (e.g., when switching playmode or recompiling) such as instances of assets, scene objects, etc. You’re correct that asset files themselves DO persist.

> [@Sabo](#):
>
> Right. I do not instantiate any asset. Pre runtime I drag the assets (talents) onto talent tree nodes (have a reference to Talent asset). During runtime I drag talent tree nodes to action bar slots, setting a talent field to reference the talent in the talent tree node. Since all I am doing is changing the reference in the action bar slot slot (which is an asset) to point to another asset (talent) I would like to think that the change should be persisted. Especially since, during runtime, dragging the very same talent from the project view and dropping it on the talent field for the action bar slot asset DO persist the change. Just does not work when dropping it during the ingame UI. And oh, I never (as far I know) instantiate any asset of any kind during runtime, just changing fields in them. Hope I am not proven wrong!

What do you mean by “ingame UI”? It sounds like it works when you use the Unity editor’s Inspector view. The Inspector properly marks assets dirty when you make changes. Perhaps your ingame UI isn’t marking the assets dirty.

---

<div class="post-metadata">

### Author: ![Sabo](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Sabo](https://discussions.unity.com/u/Sabo)
#### Post date: [January 4, 2017, 2:07pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/10 "2017-01-04T14:07:39Z")

</div>

> [@TonyLi](#):
>
> What do you mean by “ingame UI”? It sounds like it works when you use the Unity editor’s Inspector view. The Inspector properly marks assets dirty when you make changes. Perhaps your ingame UI isn’t marking the assets dirty.

By “ingame UI” I mean the UI used when playing the game (vs the Unity UI you use when developing the game).

Am I supposed to mark the assets as dirty through code? Thought was handled automagically whenever a change to the asset occurred? As far as I know, the only way to explicitely mark an asset as dirty is through Editor classes?

---

<div class="post-metadata">

### Author: ![Baste](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/baste/32/880289_2.png) [@Baste](https://discussions.unity.com/u/Baste)
#### Post date: [January 4, 2017, 2:12pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/11 "2017-01-04T14:12:14Z")

</div>

Oh.

You’re changing the instantiated version of the ScriptableObject through an in-game UI? I (and probably @TonyLi ) were assuming you had selected the Scriptable in the hierarchy and edited it in the inspector.

That won’t persist. That would allow you to change the state on disk of the ScriptableObject _in a build_. Can’t do that. As you’ve realized, making the scriptable save requires you to set it dirty, which is an editor-only feature (as it’s got to do with the editor).

If you want the user to be able to persist changes through an in-game UI, you’ll have to save that data to file in some way.

---

<div class="post-metadata">

### Author: ![TonyLi](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/tonyli/32/611093_2.png) [@TonyLi](https://discussions.unity.com/u/TonyLi)
#### Post date: [January 4, 2017, 4:10pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/12 "2017-01-04T16:10:48Z")

</div>

…such as [JsonUtility](https://docs.unity3d.com/ScriptReference/JsonUtility.html). You can create a new instance of your ScriptableObject and use JsonUtility.FromJsonOverwrite. It will serialize most primitive data (ints, strings, arrays, etc.), but how it handles references will depend on how those references are implemented.

(And sorry about the confusion earlier. As Baste suggested, I thought you were talking about making changes to your ScriptableObject asset in the editor using some kind of ingame UI, for example to tweak gameplay values. This would work, but only in the editor.)

---

<div class="post-metadata">

### Author: ![Sabo](https://avatars.discourse-cdn.com/v4/letter/s/eb8c5e/32.png) [@Sabo](https://discussions.unity.com/u/Sabo)
#### Post date: [January 4, 2017, 5:06pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/13 "2017-01-04T17:06:03Z")

</div>

Oh, ok. I see what you are saying. That is… unfortunate. Was hoping Assets would allow me save data in an easy way. Never much liked the way Unity deals with serialization, something pretty every game needs.

A huge thanks to you for taking the time to help me out.

---

<div class="post-metadata">

### Author: ![TonyLi](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/tonyli/32/611093_2.png) [@TonyLi](https://discussions.unity.com/u/TonyLi)
#### Post date: [January 4, 2017, 6:04pm UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/14 "2017-01-04T18:04:34Z")

</div>

I know what you’re talking about. But one of the nice things about Unity is its extensibility. There are other serialization options out there, too.

---

<div class="post-metadata">

### Author: ![illinar](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/illinar/32/119463_2.png) [@illinar](https://discussions.unity.com/u/illinar)
#### Post date: [October 28, 2020, 10:52am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/15 "2020-10-28T10:52:47Z")

</div>

For those who google this. You can make SO persistent by calling `.SetDirty()` on them and then calling `AssetDatabase.SaveAssets()`

---

<div class="post-metadata">

### Author: ![MrPaparoz](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/mrpaparoz/32/102365_2.png) [@MrPaparoz](https://discussions.unity.com/u/MrPaparoz)
#### Post date: [October 28, 2020, 11:14am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/16 "2020-10-28T11:14:59Z")

</div>

> [@illinar](#):
>
> For those who google this. You can make SO persistent by calling `.SetDirty()` on them and then calling `AssetDatabase.SaveAssets()`

but remember, you can’t call AssetDatabase in build.

---

<div class="post-metadata">

### Author: ![mat108](https://avatars.discourse-cdn.com/v4/letter/m/65b543/32.png) [@mat108](https://discussions.unity.com/u/mat108)
#### Post date: [May 15, 2021, 9:37am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/17 "2021-05-15T09:37:08Z")

</div>

It would have been way too easy to just give developers the possibility of saving persistant data in scriptable Objects. Way too easy. Instead Unity has to keep it real, and leave that option out.

‘But scriptable objects aren’t meant to be used that way’

Says who. Leave people the option to use tools in the way they see fit. Saving data persistantly in SO’s would have been INCREDIBLY convenient. Way too convenient, as I stated. No convenience allowed!!

---

<div class="post-metadata">

### Author: ![system](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/system/32/97283_2.png) [@system](https://discussions.unity.com/u/system)
#### Post date: [May 15, 2021, 10:15am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/18 "2021-05-15T10:15:21Z")

</div>

> [@mat108](#):
>
> It would have been way too easy to just give developers the possibility of saving persistant data in scriptable Objects. Way too easy. Instead Unity has to keep it real, and leave that option out.
> 
> ‘But scriptable objects aren’t meant to be used that way’
> 
> Says who. Leave people the option to use tools in the way they see fit. Saving data persistantly in SO’s would have been INCREDIBLY convenient. Way too convenient, as I stated. No convenience allowed!!

You’re missing some “small” problems around this: your scriptable objects are in big compressed libraries when you are installing your game. Unity would have to develop some sort of saving system for you, but since they do not know your game, they really can’t do it on a satisfying way, so they (and we, who know what is really happening) say that you can develop your saving system, it’s really not that complicated. Gather your data what _you_ want to save and write it in a file in a format you want.

---

<div class="post-metadata">

### Author: ![mat108](https://avatars.discourse-cdn.com/v4/letter/m/65b543/32.png) [@mat108](https://discussions.unity.com/u/mat108)
#### Post date: [May 15, 2021, 10:38am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/19 "2021-05-15T10:38:10Z")

</div>

> [@](#):
>
> You’re missing some “small” problems around this: your scriptable objects are in big compressed libraries when you are installing your game. Unity would have to develop some sort of saving system for you, but since they do not know your game, they really can’t do it on a satisfying way, so they (and we, who know what is really happening) say that you can develop your saving system, it’s really not that complicated. Gather your data what _you_ want to save and write it in a file in a format you want.

You are probably right, and if I was content with a ‘dumb’ approach it would be easy to solve. But trying to create an elegant mantainable and scaleable solution is a whole different beast. I’m 100% certain that everything you mentioned would be a minor inconvenience if there was the will to allow for SO’s to store data persistantly. They could still be and remain compressed and yada yada for everyone that doesn’t need that functionality.

---

<div class="post-metadata">

### Author: ![Munchy2007](https://dub1.discourse-cdn.com/unity/user_avatar/discussions.unity.com/munchy2007/32/968287_2.png) [@Munchy2007](https://discussions.unity.com/u/Munchy2007)
#### Post date: [May 15, 2021, 11:10am UTC](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871/20 "2021-05-15T11:10:38Z")

</div>

I can’t remember where I saw it now, but I’m pretty sure I remember seeing that the option to enable saving of scriptableobject asset runtime changes when desired was something that they were looking to introduce at some point.

[Next page](https://discussions.unity.com/t/scriptableobject-changes-not-persisted/649871.md?page=2)
