← Serialization Rescue

Serialization Rescue: Manual

Version 1.0.0 · Unity 2022.3 LTS and newer · Editor only (nothing goes into your builds)

Serialization Rescue isn’t released yet. This manual describes version 1.0.0 as it will ship.

This manual covers the full edition. Serialization Rescue Lite scans and reports only: see Editions.

What the problem is

Unity stores two kinds of links by name or by ID inside your scenes, prefabs and assets.

[SerializeReference] fields store each object together with its class name, namespace and assembly:

references:
  version: 2
  RefIds:
  - rid: 1000
    type: {class: Fireball, ns: MyGame.Spells, asm: Assembly-CSharp}
    data:
      damage: 12
      radius: 2.5

Rename Fireball, move it to another namespace, or move its script into an assembly definition, and the type: line no longer matches any class. Unity then:

  • logs “Unknown managed type referenced”;
  • shows the field as empty;
  • keeps the data: in the file until someone saves over it.

Prefab overrides store the same information in another form:

propertyPath: managedReferences[1000]
value: Assembly-CSharp MyGame.Spells.Fireball

Components and ScriptableObjects store a reference to their script asset:

m_Script: {fileID: 11500000, guid: 4f0e6a0b1c2d3e4f5a6b7c8d9e0f1a2b, type: 3}

If the script’s .meta file is lost, or regenerated (for example when a file is moved outside Unity), the script gets a new GUID. Every object that used it then shows “The associated script can not be loaded”. The saved field values are still in the file.

Serialization Rescue reads these files as text, so it sees data Unity can no longer load. It finds the class or script the data belongs to now and rewrites only the type or script reference. The values stay as they are.

Installing

  • From the Unity Asset Store: open Window > Package Manager > My Assets, find Serialization Rescue, then click Download and Import. The tool goes into Assets/Steadyhand/SerializationRescue.
  • From itch.io: double-click the .unitypackage (or use Assets > Import Package > Custom Package), or unzip the UPM archive and in Window > Package Manager click + > Add package from disk… and select its package.json.

The tool works in Unity 2022.3 LTS and newer, including Unity 6. It needs the Asset Serialization Mode Force Text, which is Unity’s default (Project Settings > Editor > Asset Serialization).

Scanning

Open Tools > Steadyhand > Serialization Rescue and click Scan project.

A project scan covers Assets/ plus embedded and local packages. By default it reads these file types: .unity, .prefab, .asset, .preset, .playable, .signal and .controller. You can change the list in Settings.

Packages installed from a registry, Git or the built-in set are read-only, so they are not scanned. To scan part of a project, select folders or files in the Project window and choose Assets > Serialization Rescue > Scan Selection. You can also switch the toolbar to “Selected folders/files”.

The scan does not run while scripts are compiling, while scripts have compile errors, or in Play Mode. With compile errors Unity can’t load your classes, so every class would look missing.

The window shows three tabs:

TabShows
SerializeReference typesClasses named in your files that no loaded class matches
Missing scriptsScript references (GUID and file ID) that point to no loadable script
[MovedFrom]Old class names that load only because a [MovedFrom] attribute maps them to a new class

Each entry lists:

  • how many references or objects use it, and in how many files;
  • the field names saved in the data;
  • the files, each with a Ping button.

Suggestions

For every missing class the tool ranks the classes that exist now. There are two signals.

Name

  • The same class name in another namespace or assembly means the class was moved.
  • A similar name means it was renamed. Added prefixes and suffixes count strongly: Fireball → FireballSpell.

Fields

  • The tool compares the saved field names with each candidate’s serialized fields.
  • The candidate’s fields include public fields, [SerializeField] fields and [FormerlySerializedAs] aliases.

Generic classes are only matched to classes with the same number of generic parameters.

For missing scripts the class name is often unknown. In that case the saved fields decide. Newer Unity versions may record the class in m_EditorClassIdentifier; when that is present it is used as a hint (“recorded as …”). Unity does not always keep it up to date, so check the suggestion.

A suggestion is preselected as “Map to” only when it scores 90% or more and is clearly ahead of the next one. When several classes are about equally likely, the entry says so even when collapsed, and you choose. Nothing is written until you click Apply.

The tool’s own classes are never suggested for your data; the demo’s classes are suggested only for files inside the demo folder.

Repairing

For each missing [SerializeReference] type, choose one of three actions:

  • Leave: do nothing.
  • Map to…: point the data at an existing class. Pick a suggestion with Use, or search all classes with the drop-down. The data’s fields are matched by name when Unity loads it. Fields that no longer exist are dropped the next time the asset is saved, just as after any field rename in Unity.
  • Remove data: delete the orphaned objects. Use this only for classes you deleted on purpose. This action uses Unity’s own SerializationUtility.ClearManagedReferenceWithMissingType, so reference IDs and prefabs stay consistent. To do it, Unity re-saves the whole file; if that also drops other missing-type data in the same file that you left alone, the tool reports it, and the backup has the original.

For each missing script, choose Re-link to… and pick the script. Components can only be re-linked to MonoBehaviour scripts, and ScriptableObject assets only to ScriptableObject scripts.

On the [MovedFrom] tab you can bake a redirect. The new class name is written into the files, so you can remove the attribute later.

Then:

  1. Click Preview changes. The preview lists every file and every entry that would change, for example line 27: MyGame.Spells.Fireball, Assembly-CSharp -> MyGame.Combat.FireballSpell, Game.Combat. Copy puts the list on the clipboard.
  2. Click Apply and confirm.

Apply then works through these steps:

  1. Checks out the files if a version-control integration (Perforce, Unity Version Control) is active. Read-only files stop the repair before anything is written.
  2. Stops if an affected scene, prefab or asset has unsaved changes in the Editor, and tells you which. It never saves for you: saving objects whose data has missing types is how Unity can lose that data.
  3. Copies every affected file, as it is on disk, to Library/SerializationRescue/Backups/<date-time>/.
  4. Closes Prefab Mode and unloads the affected open scenes (other open scenes stay as they are).
  5. Rewrites the type and script references in the text. Nothing else in the files changes; line endings and byte-order marks are kept.
  6. Reimports the files, removes the data you chose to remove, reopens the scenes it closed, and clears the undo history of the reloaded assets (so Undo can’t bring the broken state back).
  7. Rescans the touched files and reports anything still missing in the Log tab and the Console.

Undo: backups

Backups > Restore … copies the files of a backup back and reimports them. It backs up the current versions first, so a restore can be undone too. The 20 most recent backups are kept.

Backups live in the Library folder, which is local to your machine and deleted when Library is cleared. Version control remains the safest undo.

[MovedFrom] attributes

After choosing a target class, Copy [MovedFrom] copies an attribute such as:

[UnityEngine.Scripting.APIUpdating.MovedFrom(false, sourceNamespace: "MyGame.Spells", sourceClassName: "Fireball")]

Put it on the new class. Unity then also loads old data that was not repaired, for example on other branches or in asset bundles built earlier.

There is a limitation: in some Unity versions, [MovedFrom] is not applied to [SerializeReference] data inside prefab overrides. Repairing the files avoids that case.

Continuous integration

Unity -batchmode -nographics -projectPath . \
  -executeMethod Steadyhand.SerializationRescue.Editor.SerializationRescueCommandLine.Check \
  -srReport Logs/serialization-rescue.txt
Exit codeMeaning
0No missing types or scripts
2Missing types or scripts found (see the report and the log)
1The check could not run: compile errors, Play Mode, assets not saved as Force Text, or both checks turned off

Options:

  • -srReport <file>: writes the full report.
  • -srNoScripts: skips the missing-scripts check.
  • -srNoTypes: skips the missing-types check.

Demo

Import the Demo sample. In the Unity Asset Store version it is the Demo/ folder. In the package version, open Package Manager > Serialization Rescue > Samples and click Import.

DemoScene.unity and SpellBook.asset are intact, so they load without warnings. The demo scripts are Editor-only, so nothing from the demo goes into your builds.

To see the problem, choose Tools > Steadyhand > Serialization Rescue Demo > Create Broken Copies. It writes the same data into a “Broken Copies” folder, saved as if three refactors had happened:

  • MyGame.Spells.Fireball was renamed to FireballSpell.
  • MyGame.Legacy.HealOverTime was moved to another namespace and assembly.
  • The Golem’s health script was re-created without its .meta file.

Then:

  1. Right-click the “Broken Copies” folder and choose Serialization Rescue > Scan Selection.
  2. Look at the suggestions:
    • Fireball → FireballSpell: similar name, 3 of 3 saved fields match.
    • HealOverTime → HealOverTime: same class name, moved.
    • The Golem’s missing script → DemoHealth: similar name, 2 of 2 saved fields match.
  3. Click Preview changes, then Apply.

The broken copies then load with all their values. To start again, delete the folder.

Limits and notes

  • Binary-serialized files can’t be read.
  • Objects with no script assigned at all ({fileID: 0}) are reported only; they are not one class.
  • A script used by both components and ScriptableObjects must be re-linked by hand.
  • Removing data is offered for [SerializeReference] types only.
  • Mapping changes only the type. If the new class renamed fields, add [FormerlySerializedAs("oldName")] to them before repairing, so Unity reads the old values.
  • The tool only edits files it scanned in Assets/ and in embedded or local packages, plus its backups in Library/.
  • The CI check exits with 1 (not 0) when the assets are not saved as Force Text, because then nothing can be read.
  • The tool collects no data, needs no account and makes no network requests.

Support

Email support@steadyhand.dev with:

  • your Unity version;
  • the report from the toolbar’s Copy report button;
  • if possible, the affected file.

AI disclosure: the code, tests and documentation of this tool were written by an AI coding assistant (Anthropic’s Claude) on the publisher’s instructions, and tested with automated unit tests; testing in the Unity Editor is in progress.