Modify a ScriptableObject class without losing the current data

Hello!
I work with hundreds of scriptable objects and as soon as I modify the class I have to recreate a scriptable object and put all the data back. This is really annoying when you have a lot of scriptable objects. So it would be nice to find a solution for this type of problem! Without dealing with Force Text serialization mode or anything…
DSCRD.

I’ll be surprised if this is possible, but people here often surprise me.

1 Like

How are you modifying it? I performed a quick test (Unity 2021.1.6) where I added variables to an SO that already had data in it and none of the data was deleted. Only by deleting the variable, letting it compile the SO, and then re-adding it back did the data get deleted.

Hey, maybe Unity surprised me…

In my experience renaming the variable names will cause any of those particular values entered in your scriptable objects to reset. So needless to say, make sure you get those variable names right. Learned that the hard way once.

Other than that, I’ve reworked my scriptable object inventory items a number of times (sans renaming variables) and have not lost any data entered.

You can migrate your data if you need to rename

I’m modifying the class, then it compiles but I have to recreate the SO to actually be able to see the variable I added.

I just fixed it, I had to add the [SerializeField] field to force Unity to serialize it, even tough it was public…

With [SerializeField]

[SerializeField]
public Image thumbnail;

Result:
7152172--856012--upload_2021-5-18_16-22-39.png
Without [SerializeField]
csharp* *public Image thumbnail;* *
Result:
Missing “Thumbnail” field

Yeah, you have to properly serialize your ScriptableObjects. It’s a whole thing because they’re designed to be serializable data types by the engine.

1 Like

There’s an attribute you can use if you need to change a name. “FormerlySerializedAs”, I think.

5 Likes

Problem with that though is that it will only mutate file on disk if you alter the asset.

Its better to migrate all instances of said scriptable object in a controlled fashion and then commit to repo.

Just imagine how darn near impossible a large project would be if this wasn’t possible, though. Having to re-enter a whole system’s data because code had to be changed would be untenable.

4 Likes

Yeah, I’m sure that’s better in some cases, where both you can do that without interrupting others and it makes a practical difference somehow. You’ve got to consider the cost on both sides.

It’s pretty Cargo Cultish to go around saying what’s “better” without explanation, context, or qualification of where it is and isn’t the case.

2 Likes

Make a new variable and have it equal the old one. Compile and then remove the old variable. It ain’t enterprise but it is simple and works. The essence of game dev.

4 Likes

What you mean? The code change have already happened. I can’t see a single use case when it’s better to not reflect that right away in the asset files.

You want to keep code change and asset change tight, its easier to maintain repo that way

You want to modify the SO and not lose the change you made when a script reload occurs? Are you also setting the SO dirty when you make the change?
https://docs.unity3d.com/2021.1/Documentation/ScriptReference/EditorUtility.SetDirty.html

This sounds like a bug. Could you file a bug report, please?

2 Likes

Might make more sense to use SerializedObjects for this instead. While it does involve custom inspectors, it’s the easiest way to make them and keep them extensible without having to fight with the awkward mess that is SetDirty/RecordObject stuff. They’re automatically flagged as dirty that way, end up with proper undo support, and kinda just offer all sorts of long-term project benefits while SetDirty is the kinda thing I reserve for edge cases and game jams now.

edit: obvious caveats like custom data types apply, of course

In a small project where only one thing happens at a time, maybe.

But past that, your idea of “better” seems to be based on very specific scenarios, or a textbook, or some imaginary ideal scenario. My idea of “better” involves maintaining the productivity of a bunch of other people who are also simultaneously working on their own challenging problems in a large project. Content development often happens in parallel to feature development, and often multiple of both are going on at once, so making everyone sync up can be costly.

And, frankly, I don’t see the benefit. The computer is perfectly capable of honoring the [FormerlySerializedAs(…)] attribute for as long as needed for assets to catch up with the code. That’s exactly the kind of thing computers are good at. Let them do it.

1 Like

Well if it’s a bug I will :wink:

1 Like