SOBackupRestore: A Simple Safety Net for Unity ScriptableObjects Stop losing data on refactors with a battle-tested, GUID-based JSON backup & restore workflow

Unity games with no audio on Windows - Obra Dinn, Hollow Knight and more - How to fix
Fork me on GitHub

SOBackupRestore is an Editor-only utility for Unity that backs up and restores ScriptableObject assets as GUID-named JSON files.

It mirrors the Inspector’s serialization (fields, lists, enums, nested data, and asset references) and can optionally remap field names (old → new) during restore, letting you refactor schemas and still push your values back into existing assets without touching your production pipeline.

The full, updated source code is available on GitHub under MIT license, meaning it can be used free of charge for any purpose.

I built SOBackupRestore because I was tired of watching carefully tuned ScriptableObject data vanish after harmless refactors—renaming a field, moving a class, shuffling namespaces. If you ship content-heavy games—or iterate aggressively—you’ve probably felt that pit-in-the-stomach moment: the code compiles, the Inspector looks fine… and your .asset values are mysteriously gone.

In this article, I’ll show what SOBackupRestore does and how to use it step by step to protect your data during refactors.

The main issue: Unity serializes by field name

Unity’s serializer keys off field names. Rename a [SerializeField] (or change a type), and existing assets can no longer match the stored keys. Unity doesn’t know where to put that data, so it gets dropped from the Inspector.

Yes, there are great tools like [FormerlySerializedAs] and [MovedFrom]—and you should use them—but real projects get messy:

  • You’re touching dozens of ScriptableObject types.
  • Some fields change multiple times across sprints.
  • Someone moved classes across assemblies/namespaces.
  • You need a guaranteed way to roll forward after a schema change.

I wanted a toolbox wrench I could reach for any time I planned a risky refactor.

What SOBackupRestore does (in one breath)

SOBackupRestore is an Editor-only utility that:

  • Backs up every ScriptableObject it finds into a pretty-printed JSON file.
  • Names each file by the asset’s GUID (not by path), so moving/renaming assets is safe.
  • Restores values into the existing assets via EditorJsonUtility.FromJsonOverwrite.
  • Optionally applies a simple field-name remap (oldKey → newKey) during restore, so you can survive aggressive renames even if you didn’t (or couldn’t) annotate everything with [FormerlySerializedAs].

Result: You can refactor with confidence, then push your data back in.

When you should use it

  • Before large refactors of ScriptableObject schemas.
  • When merging content branches where field names diverged.
  • As a lightweight migration step alongside [FormerlySerializedAs]/[MovedFrom].
  • When onboarding teammates who reorganize project folders and asset names.

It’s not a replacement for good hygiene—it’s a seatbelt that lets me move faster.

How it works (under the hood)

  • Backup: For each ScriptableObject found under selected folders, the tool writes {guid}.json containing the exact Inspector-style serialization (lists, enums, nested data, references as {fileID, guid, type}, even many SerializeReference cases).
  • Restore: For each *.json, it resolves the GUID back to an asset path, loads the ScriptableObject, optionally rewrites field keys in the JSON (string replace on "fieldName":), and calls FromJsonOverwrite to populate values. Assets are marked dirty; nothing new is created.

Because everything is keyed by GUID, path shuffles won’t break the mapping.

Quick start (Editor workflow)

  1. Put the script in an Editor folder. Any .../Editor/ path works (e.g., Assets/Tools/Editor/SOBackupRestore.cs). It must be Editor-only.
  2. Backup: In the Project window, select the folders you want (or leave nothing selected to scan all of Assets/). Use the menu: Tools → Contrappasso → Backup ScriptableObjects to JSON…. Pick an output folder (I store backups outside Assets/).
  3. Refactor: Rename fields/classes/namespaces freely. Add [FormerlySerializedAs]/[MovedFrom] where feasible.
  4. (Optional) Map field names: Open SOBackupRestore and fill the keyRenames dictionary (see below).
  5. Restore: Tools → Contrappasso → Restore ScriptableObjects from JSON…. Point it to your backup folder. Watch values flow back into assets.

Tip: Commit before and after. The JSON makes great forensic breadcrumbs in code reviews.

Field-name remapping (optional but powerful)

Drop old → new mappings into a dictionary before restoring. The tool will rewrite JSON keys and then overwrite asset values.

This is a pragmatic safety valve when you can’t annotate every renamed field (e.g., cross-team churn, multiple legacy branches). It only rewrites JSON keys (the left-hand side of "key": value), keeping values intact.

Best practices I follow alongside SOBackupRestore

  • Keep .meta files visible and Force Text serialization (Project Settings → Editor).
  • Prefer private serialized fields + public properties to reduce future renames of serialized names.
  • Add [FormerlySerializedAs] on renamed fields and leave it in for a couple of releases.
  • Use [MovedFrom] when changing class names/namespaces/assemblies.
  • During big migrations, run a backup, then a restore, then open a few “sentinel” assets/scenes and eyeball the values.

Limitations (know them, avoid surprises)

  • Only covers Unity-serializable data (public or [SerializeField]). Not static fields, not pure computed properties.
  • It overwrites values on existing assets; it doesn’t create new assets.
  • If you change types incompatibly, Unity can’t deserialize old values. Use migration code (ISerializationCallbackReceiver) for real schema changes.

Why JSON, not custom tooling?

  • JSON is transparent—diffable, greppable, easy to hot-fix.
  • EditorJsonUtility mirrors what the Inspector does. No surprises, no custom formatter to maintain.
  • Backups can live outside your project tree, so they don’t contaminate builds or CI.

Closing thoughts

SOBackupRestore doesn’t make refactors trivial—but it removes the fear. I built it to move faster on Contrappasso without playing roulette with hours of tuning buried in ScriptableObjects. If you’re juggling lots of content and you iterate hard, give this workflow a spin. Combine it with good Serializer hygiene and you’ll sleep better the next time you rename damage to baseDamage five minutes before a milestone.

If you want, I can share a trimmed “starter” template (menu items + minimal UI) or a version that targets a specific type (e.g., WeaponData only) and generates a before/after CSV for sanity checks.

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.