
Unity Generic MonoBehaviour Bug: Limitations and Workarounds (Complete Guide)
July 22, 2026
Deep Dive into Unity Prefab Overrides: The Complete Technical Guide
July 30, 2026Unity’s serialization system is one of the most misunderstood core systems in the engine.
While it appears simple on the surface—variables appear in the Inspector, components save data, prefabs keep overrides—the internal rules are strict, limited, and highly optimized.
This guide explains exactly how Unity serialization works under the hood.
1. What Serialization Means in Unity
Serialization in Unity is the process of converting Unity objects and fields into a format that can be:
- Displayed in the Inspector
- Saved into scenes
- Stored inside prefabs
- Transferred between editor sessions
Unity does not use .NET serialization.
Instead, it uses its own highly optimized C++‑based system.
2. What Types Unity Can Serialize
Unity serializes only these categories:
- Primitive types (int, float, bool, string)
- UnityEngine structs (Vector3, Quaternion, Color, etc.)
- Non-generic C# classes with
[Serializable] - Arrays and Lists of serializable types
- UnityEngine.Object references
- ScriptableObjects
- Concrete MonoBehaviours
Everything else is rejected by the serialization system.
3. What Unity Does NOT Serialize
- Generic types (no
List<T>inside custom serializable classes with unknown T) - Dictionaries
- Events and delegates
- Static fields
- Interface references
- Properties (no getters/setters)
- Abstract classes
- Classes without a parameterless constructor
If the type cannot be reflected at compile time, Unity skips it.
4. The Three Layers of Unity Serialization
4.1. The C# Layer (Reflection Level)
Unity scans C# fields using reflection and builds a “serialization layout”.
This includes:
- Field name
- Field type
- Whether it is serializable
4.2. The Native C++ Layer
Unity converts the reflection data into a native format stored inside scenes, assets, and prefabs.
This layer is extremely strict and only supports types known in advance.
4.3. The Inspector / Editor Layer
The Unity Inspector uses the serialization layout to draw UI fields.
This layer is responsible for:
- Showing values
- Detecting prefab overrides
- Applying modifications
5. How Unity Stores Data in Scenes and Prefabs
Unity stores serialized objects in YAML. Example:
m_SomeInt: 10 m_SomeVector: x: 0 y: 1 z: 5
During load, Unity reconstructs these fields into actual C# instances.
6. How Reference Serialization Works
6.1. UnityEngine.Object References
These references are stored using internal file IDs.
This allows scenes and prefabs to reference:
- Components
- GameObjects
- ScriptableObjects
- Assets
6.2. Non-Unity Objects Are Serialized by Value
Custom classes marked [Serializable] are fully copied whenever serialized.
6.3. No True Pointer Serialization
Regular C# object references are not preserved.
Every custom class is duplicated when deserialized.
7. The Backing Store Mechanism
Unity does not serialize your fields directly.
Instead, it uses a hidden “backing store” managed by native code.
For example:
public int health = 100;
Unity creates:
- A native serialized value
- A managed copy (your C# field)
These two sync during:
- Scene load
- Inspector edits
- Undo operations
8. Why Dictionaries and Generics Are Not Supported
Unity requires fixed, predictable memory layouts.
Generics and dictionaries create dynamic runtime state that Unity cannot reflect into native format.
9. Serialization Cycles and Instability
Some types (especially custom classes referencing each other) can cause:
- Infinite loops
- Missing references
- Data loss
- Editor crashes
Unity works around this with internal safeguards, but these still cause errors in complex nested data structures.
10. Best Practices for Clean and Safe Serialization
- Keep fields public or mark with
[SerializeField] - Avoid dictionaries (use lists of key-value structs)
- Avoid nested generics
- Make all custom classes [Serializable]
- Use ScriptableObjects for shared data
- Avoid runtime-generated types
- Keep MonoBehaviours non-generic
Conclusion
Unity’s serialization system is powerful but limited.
It is built for performance, determinism, and editor stability—not for general-purpose .NET flexibility.
Understanding these rules allows developers to build safer, faster, and more reliable systems.








