ScriptableObject is not Saving after code editing?

Hi there!
So I am attempting to make a gold balancing script in which it will balance every single item I have in my game.
I want it to iterate through the Recipes and add up all the gold and change its “buyPrice” and “sellPrice”.

The script works fine and changes the ScriptableObject’s buyPrice and sellPrice.
My issue is when I close and reopen unity, the buyPrices and sellPrices were NOT saved.

How can I fix this issue? I am doing the following:

EditorUtility.SetDirty(r);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();

Here is the code:

public void BalanceSmithingGold() {
        System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
        int done = 0;
        ScriptableSmithingRecipe[] recipes = Resources.LoadAll<ScriptableSmithingRecipe>("");

        foreach (ScriptableSmithingRecipe r in recipes) {

            if (r.result == null)
                continue;

            long g = 0;

            for (int i = 0; i < r.ingredients.Count; i++) {
                if (r.ingredients[i].item == null)
                    continue;

                bool isCraftable = false;
                foreach (ScriptableSmithingRecipe sr in recipes) {
                    if (r.ingredients[i].item == sr.result) {
                        g += getCraftableItemValue(sr) * r.ingredients[i].amount;
                        isCraftable = true;
                        break;
                    }
                }

                if (!isCraftable)
                    g += r.ingredients[i].item.buyPrice * r.ingredients[i].amount;




            }

            done++;
            if (r.resultQuantity > 1)
                g /= r.resultQuantity;
            r.result.buyPrice = g;
            r.result.sellPrice = (long)(g * sellValue);
            EditorUtility.SetDirty(r);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

        }



        stopwatch.Stop();
        Debug.LogWarning(done + " item's gold in Smithing Recipes changed in " + stopwatch.ElapsedMilliseconds + "ms.");
    }
GoldBalancer.singleton.BalanceSmithingGold();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();

Is everything properly marked as System.Serializable? You left out ALL the shape of your actual data containers.

1 Like

The only thing I am changing is the “buyPrice” and “sellPrice” which are just integers and integers are a serializable thats why it shows up in the Inspector when I click on my ScriptableObject.

You could try calling SetDirty before making your changes to the buyPrice and sellPrice. I’ve been more paranoid about my editor scripts, calling SetDirty before and after making changes.

Thanks for the suggestion, but I tried SetDirty before, after, and both. Still doesn’t save after restarting unity :confused:

Guessing Recipes is a list, and not of a simple variable. It’s very tricky (or maybe just not possible, I’m not great with serializing classes myself.) to get lists or arrays to serialize properly when they contain non-built in classes.

I just had to reconstruct a class which handles all my object interactions in my game to not have variables to save. Instead I went with an awkward solution of having multiple lists which contained the simple variables needed in a different class. In my case, three list and a list, and I just always add to them at the same time, and pass the variables to the Action class when I call it.

Man sounds like a hassle :L
However, in my case my "ScriptableSmithingRecipe " is just simply a ScriptableObject in which has normal variables such as ints, strings, etc.
Nothing that is not serializable.

Oh it certainly is. From what I’ve gathered researching the last few days, unity simply doesn’t allow lists (or array) to serialized as part of the class itself.

Another option (I think) that worked for me on an old project was to explicitly serialize/save the list as a separate file.

Using serialization.binaryFormatter to save the needed data, then load the lists back in on awake and just actualList =listSave;

I only know where to put these files as a save file, not a game file (where you don’t want people messing with it) but I can post that code example if you want.

haha fixed the solution. Just a simple oversight…
I am changing the values “r.result.buyPrice” and “r.result.sellPrice”
and then attempting to tell unity to save it by doing “EditorUtility.SetDirty(r);”
which is wrong. I am not changing “r” I am changing the “r.result” variables.
I changed it to “EditorUtility.SetDirty(r.result);”
and all is well now :wink: