The manager decides where your data is saved; the serializer decides how it is written. It is a dropdown right under the manager, and it can be changed at any time.

Which one to use

Unity JSON is the default, and it covers typical data. The other two exist for what Unity's own serialization cannot describe: a Dictionary, an interface or abstract field, or a plain C# class hierarchy.

SerializerWritesNeedsBest for
Unity JSON Exactly what Unity serializes: public fields and [SerializeField] ones. Nothing, it is built in. Almost every game: what you see in the inspector is what gets saved.
Newtonsoft JSON That, plus dictionaries, properties, nullables and (optionally) polymorphic types. The Newtonsoft Json package. Data shaped like real C# rather than like Unity: dictionaries and object graphs, while staying readable JSON.
Odin That, plus objects referenced from several places kept as one object. Odin Inspector, or the free Odin Serializer. Projects already using Odin, and data that is a graph rather than a tree.

All three save a reference to a project asset the same way, through asset references.

A serializer whose dependency is not installed does not appear in the dropdown at all.

Unity JSON

The default. It serializes your fields exactly the way Unity already does, with the same rules as the inspector and prefabs, and needs no setup.

  • Pretty Print: readable, indented JSON, so a save can be opened and read while building the game.
  • One Line: the same JSON without the whitespace.
  • Obfuscated: one line, base64 encoded, so a player poking at the file sees nothing readable. This is obfuscation, not encryption: use the manager's security options for that.

Its limits are Unity's limits: no dictionaries, no properties, no null for a serializable class, and an interface or abstract field only through [SerializeReference].

Newtonsoft JSON

Appears once the Newtonsoft Json package is in the project. Install it from the Package Manager (Add package by name, com.unity.nuget.newtonsoft-json); the serializer shows up in the dropdown as soon as it finishes importing, with nothing else to configure.

It writes everything Unity would have written, plus everything Newtonsoft would have written. Switching an object from Unity JSON to Newtonsoft therefore never drops a field that used to be saved, and adds the members Unity cannot express.

  • Dictionaries, nullables, plain C# objects and anything else Newtonsoft handles, with no attributes needed.
  • Properties are saved too, under their own name (a [field: SerializeField] auto property is written as Gold here, where Unity writes <Gold>k__BackingField).
  • Opt in or out per member with Newtonsoft's own [JsonProperty] and [JsonIgnore], on top of [SerializeField] and [NonSerialized].
  • Shared references, when turned on, keeps an object referenced from several places as one object instead of writing a copy at each place. It also lets data refer back to itself without losing the reference.
  • Polymorphic types, when turned on, writes the concrete type of values held in interface, abstract or base class fields, so they load back as the right subclass.
Polymorphic types come with two constraints: the type name becomes part of the save format, so renaming or moving a class breaks existing saves, and a save file a player edited can then name any type in the game. The security options cover the second one.

One thing it does not carry over: Unity calls ISerializationCallbackReceiver on your nested types, and Newtonsoft does not. If a nested type relies on those callbacks to flatten itself, move that work to the persistent object's own ISerializationCallbacks.

Odin

Appears once Odin is in the project, in either of its two shapes: the serializer bundled with Odin Inspector, or the free standalone Odin Serializer. Either one works, with nothing to set up.

It covers the same ground as Newtonsoft, and adds Odin's own strengths: shared references and polymorphic types are on by default, and it handles types that neither Unity nor a JSON serializer would write.

  • Json: readable output, and the only format that can feed save upgrades their old values.
  • Binary: smaller and faster, stored base64 encoded, unreadable to players. Save upgrades cannot read old values from it, and the editor tells you so if you configure an object that needs them.
Odin needs its AOT support generated before an IL2CPP build (from its own tools menu), otherwise types that only ever appear in save data can be stripped from the player and the load fails there while working in the editor.

If the standalone Odin Serializer is in your project as source files with your own assembly definition, the package will say so in the console: it can only reach it as a plugin (its own .dll under Assets/Plugins), or if you add that assembly to the references of PersistentAsset.BuiltIns.Odin.asmdef.

Changing serializer later

Each serializer writes a different format, so a save written by one cannot be read by another. The package treats that like any other save-breaking change: when you switch the serializer of an object that already shipped, it offers to keep the old setup as an import source, so existing players' saves are read once in the old format and written back in the new one.

While the game is unreleased, deleting the test saves (Tools > Persistent Asset > Actions > Delete Local Data) is all it takes.

Your own

Inherit Serializer and your class appears in the dropdown next to the built-in ones. See Extending.