Quick answer: Add an Assets/link.xml with explicit preserve entries for assemblies and types your code reflects on. Apply [Preserve] to specific reflected members. Lower Managed Stripping Level to Low if you can’t enumerate every reflected type.

JsonUtility.FromJson works fine in Editor. IL2CPP build returns an object with all default values. The fields’ setters were stripped because the linker only sees them touched by reflection.

The Symptom

Reflection-based code (JSON deserialization, Newtonsoft, custom inspector serialization, dependency injection) returns null/default values in IL2CPP builds. Editor and Mono builds work. Errors may say “TypeLoadException” or be silent.

The Fix

Pattern 1: link.xml preserve.

<!-- Assets/link.xml -->
<linker>
  <assembly fullname="YourGame">
    <type fullname="Game.Save.SaveData" preserve="all" />
    <type fullname="Game.Save.*" preserve="all" />
  </assembly>
  <assembly fullname="Newtonsoft.Json" preserve="all" />
</linker>

preserve=“all” keeps types, fields, methods, properties. Use sparingly — preserving everything balloons the build.

Pattern 2: Preserve attribute.

using UnityEngine.Scripting;

[Preserve]
[Serializable]
public class SaveData
{
    [Preserve] public int level;
    [Preserve] public string playerName;
}

Per-class. Useful for one-offs.

Pattern 3: Lower stripping level. Player Settings → Other Settings → Managed Stripping Level → Low. Build is bigger but reflection works without explicit preserves.

JsonUtility Specific

JsonUtility uses [SerializeField] members. If those members are also marked [Preserve] (or the type is in link.xml), the linker keeps them. Without preserve, [SerializeField] alone isn’t enough at High stripping level.

Verifying

Build IL2CPP. Run on device. Reflection code should produce expected values. If something is still missing, the build log lists stripped types in the IL2CPP step (verbose build report).

“link.xml. [Preserve]. Or lower Stripping. Reflection survives.”

Related Issues

For asmdef circular, see asmdef. For Burst BC1006, see Burst.

Preserve what reflection touches. Builds work.